一、客户端模式的认证流程
客户端模式也是一种比较简单的模式,其跟密码模式类似,只是不用用户名和密码去认证,而使用AppID、AppSecret认证。在客户端模式下,认证的主体是应用,而非用户。
二、客户端模式的实现
客户端模式的实现过程跟密码模式基本是一致的,相同的部分不再赘述,所以还没了解密码模式的读者请先阅读上一章。
我们在上一章中,创建了一个简单的Controller作为资源示例,创建了一个Startup类,作为网站入口。这些内容在客户端模式下都是完全相同的。唯一有区别的是AuthorizationServerProvider类的实现。
在密码模式下,请求host/token时,需要传入grant_type,username,password三个参数,其中grant_type为password。
在客户端模式下,同样请求host/token这个地址,需要传入grant_type,client_id,client_secret三个参数,其中grant_type为client_credentials。
当grant_type为password时,AuthorizationServerProvider这个类会把数据交给GrantResourceOwnerCredentials这个函数处理,而当grant_type为client_credentials时,将会交给GrantClientCredentials函数处理。
上述的内容我们整理为以下表格:
模式 | grant_type | 参数 | 处理函数 |
密码模式 | password | username、password | GrantResourceOwnerCredentials |
客户端模式 | client_credentials | client_id、client_secret | GrantClientCredentials |
下面是AuthorizationServerProvider类的具体实现:
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
//从上下文中获取ClientID和ClientSecret
context.TryGetFormCredentials(out string clientId, out string clientSecret);
//非法客户端
if (clientId == null || !clientId.StartsWith("AAA"))
{
context.SetError("invalid_clientId", "客户端没有授权");
return Task.FromResult<object>(null);
}
//合法客户端
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
//允许跨域访问
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
//获取客户端ID
string ClientId = context.ClientId;
//以下即为认证成功
//通过查数据库,得到一些客户端的信息
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("clientid", ClientId));
context.Validated(identity);
}
}
使用Postman进行测试: