大约一个月前,我有一个项目可以完美地使用ASP Identity OAuth。我会用grant_type、用户名和密码向/Token端点发送POST请求,一切都很顺利。
我最近开始了一个基于VisualStudio2013RC2的SPA模板的新项目。它与旧模板有点不同。身份验证设置为非常基本的默认值,
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
//AuthorizeEndpointPath = new PathString("/Account/Authorize"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
与默认模板相比没有任何重大更改。我可以通过我已经实现的Web API控制器方法成功注册帐户;
// 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);
}
然而,无论我向/Token端点POST什么,我总是得到相同的响应。
{"error":"invalid_client"}
通常我会通过以下请求正文
grant_type=password&username=user%40domain.com&password=userpassword
但这会导致同样的错误。这在以前的VS2013 SPA模板/Identity中起作用。发生了什么变化?
谢谢!
您必须覆盖ValidateClientAuthentication&OAuthAuthorizationServerProvider中的GrantResourceOwnerCredentials。
请参阅此处的示例:http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1
因此,新模板不包括旧模板中存在的ApplicationOAuthProvider的功能实现。
在观看了本次构建演讲后,我进行了进一步的研究,发现ApplicationOAuthProvider的工作实现可以在这个NuGet包中查看!它与旧的实现非常相似。
此外,当选择"个人用户帐户"作为"安全"选项时,您可以使用WebApi模板附带的ApplicationOAuthProvider类。然而,你必须改变其他一些事情,我在下面列出了这些。我希望它能有所帮助。
WebApi/个人用户帐户模板附带的ApplicationOAuthProvider类包含以下方法:
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);
}
将其复制到SPA模板项目中的ApplicationOAuthProvider类中,覆盖原始方法。代码user.GenerateUserIdentityAsync
方法在复制到SPA模板项目时无效,因为ApplicationUser类不允许"承载"身份验证类型。
向ApplicationUser类添加类似于以下内容的重载(在ModelsIdentityModels.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;
}
您现在应该能够正确使用/Token
端点了。