一、用戶端模式的認證流程
用戶端模式也是一種比較簡單的模式,其跟密碼模式類似,隻是不用使用者名和密碼去認證,而使用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進行測試: