我正在为我的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
错误。 我想处理它,但我不知道该怎么做。
ValidateClientAuthentication是您执行身份验证检查的地方,如果有任何不匹配,您将在此处抛出错误。
将代码移动到此处并在调用上下文之前执行检查。已验证((。只有在确保正确验证所有内容后,才调用 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或设置了错误的值。
就我而言,我必须设置这个:
"grant_type"、"密码">