17

Circa un mese fa ho avuto un progetto perfettamente funzionante con ASP identità OAuth. Mi piacerebbe inviare una richiesta POST per l'endpoint/Token con grant_type, il nome utente e la password, e tutto era da dandy.ricevendo sempre errore 'invalid_client' quando postando/endpoint provvisoria con ASP Identità 2

Recentemente ho iniziato un nuovo progetto in base al largo di Visual Studio 2013 modello SPA RC2. È un po 'diverso dal vecchio modello. L'autenticazione è impostato per default piuttosto semplice,

OAuthOptions = new OAuthAuthorizationServerOptions 
{ 
    TokenEndpointPath = new PathString("/Token"), 
    //AuthorizeEndpointPath = new PathString("/Account/Authorize"), 
    Provider = new ApplicationOAuthProvider(PublicClientId), 
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
    AllowInsecureHttp = true 
}; 

Niente di significativo è cambiato dal modello predefinito. Posso registrare gli account con successo attraverso un metodo di controllo API Web che ho implementato;

// POST: /Account/Register 
    [HttpPost] 
    [AllowAnonymous] 
    public async Task<IHttpActionResult> Register(RegisterBindingModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new TunrUser() { UserName = model.Email, Email = model.Email, DisplayName = model.DisplayName }; 
      var result = await UserManager.CreateAsync(user, model.Password); 
      if (result.Succeeded) 
      { 
       return Created(new Uri("/api/Users/" + user.Id,UriKind.Relative), user.toViewModel()); 
      } 
      else 
      { 
       return BadRequest(result.Errors.First()); 
      } 
     } 
     return BadRequest(ModelState); 
    } 

Tuttavia, non importa quello che post per l'endpoint/Token, ho sempre ottenere la stessa risposta.

{"error":"invalid_client"} 

Normalmente passaggio seguente corpo della richiesta

grant_type=password&username=user%40domain.com&password=userpassword 

Ma questo si traduce nello stesso errore. Questo ha funzionato nel precedente modello/identità di VS2013 SPA. Cosa è cambiato?

Grazie!

risposta

2

Così si scopre che i nuovi modelli non includono un'implementazione funzionale di ApplicationOAuthProvider che era presente nei modelli più vecchi.

Dopo aver visto this build talk, ho indagato ulteriormente e ha scoperto che un'implementazione di lavoro del ApplicationOAuthProvider è disponibile per il check-out in this NuGet package! È molto simile alla vecchia implementazione.

0

Inoltre, è possibile utilizzare la classe ApplicationOAuthProvider che viene fornito con il modello WebAPI quando account utente individuali viene scelto come opzione di sicurezza. Tuttavia, dovrai modificare un paio di altre cose, che ho elencato di seguito. Spero possa essere d'aiuto.

La classe ApplicationOAuthProvider che viene fornito con il WebAPI/Account Utente Individuali modello contiene il seguente metodo:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 
     var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); 

     ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); 

     if (user == null) 
     { 
      context.SetError("invalid_grant", "The user name or password is incorrect."); 
      return; 
     } 

     ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, 
      OAuthDefaults.AuthenticationType); 
     ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, 
      CookieAuthenticationDefaults.AuthenticationType); 

     AuthenticationProperties properties = CreateProperties(user.UserName); 
     AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); 
     context.Validated(ticket); 
     context.Request.Context.Authentication.SignIn(cookiesIdentity); 
    } 

Copia questo alla classe ApplicationOAuthProvider nel progetto modello SPA, sovrascrivendo il metodo originale. Il metodo di codice user.GenerateUserIdentityAsync non è valida quando copiato il progetto modello SPA perché la classe ApplicationUser non consente il tipo di autenticazione "portatore".

Aggiungi un sovraccarico simile al seguente alla classe ApplicationUser (si trova nel file Models\IdentityModels.cs):

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager , string authenticationType) 
    { 
     var userIdentity = await manager.CreateIdentityAsync(this , authenticationType); 
     // Add custom user claims here 
     return userIdentity; 
    } 

si dovrebbe ora essere in grado di utilizzare /Token endpoint correttamente.

Problemi correlati