使用ASP Identity 2 POST到/ Token端点时始终收到'invalid_client'错误

时间:2014-04-29 16:52:27

标签: c# asp.net asp.net-web-api asp.net-identity asp.net-web-api2

大约一个月前,我有一个与ASP Identity OAuth完美配合的项目。我使用grant_type,username和password向/ Token端点发送POST请求,所有这些都是花花公子。

我最近开始了一个基于Visual Studio 2013 RC2的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端点发布什么,我总是得到相同的响应。

{"error":"invalid_client"}

通常我会传递以下请求正文

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

但这会导致同样的错误。这适用于之前的VS2013 SPA模板/身份。什么改变了?

谢谢!

3 个答案:

答案 0 :(得分:16)

您必须覆盖ValidateClientAuthentication&amp; OAuthAuthorizationServerProvider中的GrantResourceOwnerCredentials。

见这里的例子: http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1

答案 1 :(得分:3)

事实证明,新模板不包含旧模板中存在的ApplicationOAuthProvider的功能实现。

在观看this build talk之后,我进一步调查了一下,发现ApplicationOAuthProvider的工作实现可以在this NuGet package中查看!它与旧的实现非常相似。

答案 2 :(得分:1)

此外,当选择“个人用户帐户”作为“安全性”选项时,您可以使用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类,覆盖原始方法。复制到SPA模板项目时,代码user.GenerateUserIdentityAsync方法无效,因为ApplicationUser类不允许&#34; bearer&#34;身份验证类型。

向ApplicationUser类添加类似于以下的重载(在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;
    }

您现在应该能够正确使用/Token端点。