OAuth 2.0 預設四種授權模式(GrantType): 授權碼模式( ) 簡化模式( ) 密碼模式( ) 客戶端模式( ) 使用 IdentityServer4,我們可以自定義授權模式嗎?答案是可以的,比如我們自定義實現一個 授權模式(匿名訪問)。 創建 (繼承 ): 修改 配置: DI 增加 ...
OAuth 2.0 預設四種授權模式(GrantType):
- 授權碼模式(
authorization_code
) - 簡化模式(
implicit
) - 密碼模式(
password
) - 客戶端模式(
client_credentials
)
使用 IdentityServer4,我們可以自定義授權模式嗎?答案是可以的,比如我們自定義實現一個anonymous
授權模式(匿名訪問)。
創建AnonymousGrantValidator
(繼承IExtensionGrantValidator
):
public class AnonymousGrantValidator : IExtensionGrantValidator
{
private readonly ITokenValidator _validator;
public AnonymousGrantValidator(ITokenValidator validator)
{
_validator = validator;
}
public string GrantType => "anonymous";
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
//var userToken = context.Request.Raw.Get("token");
//if (string.IsNullOrEmpty(userToken))
//{
// context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
// return;
//}
//var result = await _validator.ValidateAccessTokenAsync(userToken);
//if (result.IsError)
//{
// context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
// return;
//}
// get user's identity
//var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;
var claims = new List<Claim>() { new Claim("role", GrantType) }; // Claim 用於配置服務站點 [Authorize("anonymous")]
context.Result = new GrantValidationResult(GrantType, GrantType, claims);
}
}
修改Client
配置:
new Client
{
ClientId = "client1",
AllowedGrantTypes = GrantTypes.List(GrantTypes.ResourceOwnerPassword.FirstOrDefault(), "anonymous"), //一個 Client 可以配置多個 GrantType
AllowOfflineAccess = true,
AccessTokenLifetime = 3600 * 6, //6小時
SlidingRefreshTokenLifetime = 1296000, //15天
ClientSecrets =
{
new Secret("123".Sha256())
},
AllowedScopes = new List<string>
{
"api2"
}
}
DI 增加註入對象:
builder.AddExtensionGrantValidator<AnonymousGrantValidator>();
調用示例代碼:
public async Task<TokenResponse> AnonymousAsync(string userToken)
{
var payload = new
{
token = userToken
};
// create token client
var client = new TokenClient(disco.TokenEndpoint, "client1", "123");
// send custom grant to token endpoint, return response
return await client.RequestCustomGrantAsync("anonymous", "api2", payload);
}
Http 訪問示例:
POST /connect/token
grant_type=anonymous&
scope=api2&
token=...&
client_id=api1.client
client_secret=secret
參考資料: