【问题标题】:Always receiving 'invalid_client' error when POSTing to /Token endpoint with ASP Identity 2使用 ASP Identity 2 发布到 /Token 端点时总是收到“invalid_client”错误
【发布时间】:2014-06-15 17:57:14
【问题描述】:

大约一个月前,我有一个项目与 ASP Identity OAuth 完美配合。我会使用grant_type、用户名和密码向 /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 模板/身份中有效。有什么变化?

谢谢!

【问题讨论】:

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


    【解决方案1】:

    您必须覆盖 OAuthAuthorizationServerProvider 中的 ValidateClientAuthentication 和 GrantResourceOwnerCredentials。

    请参见此处的示例: http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1

    【讨论】:

    • 当你覆盖ValidateClientAuth,你还必须调用context.Validated();让它工作。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      In addition, you can use the ApplicationOAuthProvider class that comes with the WebApi template when Individual User Accounts is chosen as the Security option.但是,您必须更改我在下面列出的其他一些内容。希望对你有帮助。

      WebApi/Individual User Accounts模板自带的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类不允许“bearer”认证类型。

      向 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 端点了。

      【讨论】:

        猜你喜欢
        • 2020-07-14
        • 1970-01-01
        • 2016-11-26
        • 2017-04-24
        • 1970-01-01
        • 2018-03-24
        • 2016-02-25
        • 2015-05-10
        相关资源
        最近更新 更多