OAuthAuthorizationServerProvider的invalid_grant

时间:2018-05-04 10:15:48

标签: asp.net-web-api asp.net-identity

我正致力于为我的WebAPi编写完全自定义的ASP.NET标识。

我已经用这种方式重写了我自己的派生OAuthAuthorizationServerProvider:

 public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
 {
     context.Validated();
     return Task.FromResult<object>(null);
 }

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
 {
     // Check User availability ...
     //ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

     // if i couldn't found user in my DataBase ... 
     //if (user == null)
     //{
     //context.SetError("invalid_grant", "The user name or password is incorrect.");
     //    return;
     //}

     context.Validated();
 }
}

GrantResourceOwnerCredentials只会为每次调用返回invalid_grant错误。我想处理它但是,我不知道如何。

1 个答案:

答案 0 :(得分:0)

ValidateClientAuthentication 是您进行身份验证检查的地方,如果有任何不匹配的话,这就是您抛出错误的地方。

将代码移到那里并在调用context.Validated()之前进行检查。只有在确保所有内容都经过正确验证后才能调用Validate方法。

这是我做了一段时间的这种实现的一个例子:

public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientId;
            string clientSecret;

            //first try to get the client details from the Authorization Basic header
            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                //no details in the Authorization Header so try to find matching post values
                context.TryGetFormCredentials(out clientId, out clientSecret);
            }

            if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret))
            {
                context.SetError("client_not_authorized", "invalid client details");
                return Task.FromResult<object>(null);
            }

            var dataLayer = new RepoManager(new DataLayerDapper()).DataLayer;
            var audienceDto = dataLayer.GetAudience(clientId);

            if (audienceDto == null || !clientSecret.Equals(audienceDto.Secret))
            {
                context.SetError("unauthorized_client", "unauthorized client");
                return Task.FromResult<object>(null);
            }

            context.Validated();
            return Task.FromResult<object>(null);
        }

请注意检查是如何按顺序发生的,并且会引发某些错误并带来一些错误。

此代码从授权标头中获取客户端ID和客户端密钥,但您可以轻松删除所有这些并将其替换为您自己的检查和数据库调用。

重要的是,这是您处理此类内容的地方,这是您设置错误的地方,以便您的客户知道发生了什么。

GrantResourceOwnerCredentials 这是您在正确验证呼叫后获得的位置,此时您可以开始创建令牌,添加声明并创建身份验证票证。如果前一个方法无法验证请求,则不会触发此方法。

这是一个有效的例子:

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            var identity = new ClaimsIdentity("JWT");                                            
            identity.AddClaim(new Claim("clientID", context.ClientId));

            var props = new AuthenticationProperties(new Dictionary<string, string>
                {
                    {
                         "audience", context.ClientId 
                    }                    
                });

            var ticket = new AuthenticationTicket(identity, props); 
            context.Validated(ticket);
            return Task.FromResult<object>(null);
        }

现在,如果您收到无效授权错误,通常是因为您未在初始调用中设置 grant_type ,或者设置了错误的值。

就我而言,我必须设置这个:

&#34; grant_type&#34;,&#34;密码&#34;