Ricevendo sempre l’errore ‘invalid_client’ quando si esegue il POSTing to / Token endpoint con ASP Identity 2

Circa un mese fa avevo un progetto perfettamente funzionante con ASP Identity OAuth. Manderei una richiesta POST all’endpoint / Token con grant_type, username e password, e tutto era dandy.

Di recente ho avviato un nuovo progetto basato sul modello SPA di Visual Studio 2013 RC2. È un po ‘diverso dal vecchio modello. L’autenticazione è impostata su valori di default piuttosto semplici,

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 modificato 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 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); } 

Comunque, non importa cosa io POST all’endpoint / Token, ottengo sempre la stessa risposta.

 {"error":"invalid_client"} 

Normalmente passo il seguente corpo di richiesta

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

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

Grazie!

Devi eseguire l’override di ValidateClientAuthentication e GrantResourceOwnerCredentials in OAuthAuthorizationServerProvider.

Vedi esempio qui: http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1

Di conseguenza, i nuovi modelli non includono un’implementazione funzionale di ApplicationOAuthProvider che era presente nei modelli precedenti.

Dopo aver assistito a questo intervento , ho esaminato ulteriormente e ho scoperto che un’implementazione funzionante di ApplicationOAuthProvider è disponibile per il check-out in questo pacchetto NuGet ! È molto simile alla vecchia implementazione.

Inoltre, è ansible utilizzare la class ApplicationOAuthProvider fornita con il modello WebApi quando si sceglie Account utente individuale come opzione di sicurezza. Tuttavia, dovrai modificare un paio di altre cose, che ho elencato di seguito. Spero possa essere d’aiuto.

La class ApplicationOAuthProvider fornita con il modello WebApi / Account utente individuale contiene il seguente metodo:

  public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var userManager = context.OwinContext.GetUserManager(); 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 nella class ApplicationOAuthProvider nel progetto del modello SPA, sovrascrivendo il metodo originale. Il codice user.GenerateUserIdentityAsync method non è valido quando viene copiato nel progetto di modello SPA poiché la class ApplicationUser non consente il tipo di autenticazione “bearer”.

Aggiungi un overload simile al seguente alla class ApplicationUser (trovalo nel file Models\IdentityModels.cs ):

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

Ora dovresti essere in grado di utilizzare correttamente l’endpoint /Token .