OAuth 2.0 默認四種授權模式(GrantType)
- 授權碼模式(authorization_code)
- 簡化模式(implicit)
- 密碼模式(password)
- 客戶端模式(client_credentials)
使用 IdentityServer4 自定義授權模式,比如自定義實現一個 anonymous 授權模式
創建 AnonymousGrantValidator.cs 文件,繼承 IExtensionGrantValidator 接口(Interface)
using IdentityServer4.Models;
using IdentityServer4.Validation;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace AuthService.Security
{
public class AnonymousGrantValidator : IExtensionGrantValidator
{
private readonly ITokenValidator _validator;
public AnonymousGrantValidator(ITokenValidator validator)
{
_validator = validator;
}
public string GrantType => "anonymous";
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
Dictionary<string, object> customResponse = new Dictionary<string, object>();
var userToken = context.Request.Raw.Get("token");
if (string.IsNullOrEmpty(userToken))
{
customResponse.Add("code", Convert.ToString((int)EnumCode.UnAuthorized));
customResponse.Add("msg", "未授權");
//context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
context.Result = new GrantValidationResult(TokenRequestErrors.UnauthorizedClient, "未授權",customResponse);
return;
}
var result = await _validator.ValidateAccessTokenAsync(userToken);
if (result.IsError)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
return;
}
var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;
var claims = new List<Claim>()
{
new Claim("role", GrantType)
};
context.Result = new GrantValidationResult(GrantType, GrantType, claims);
}
}
}
In Clients.cs
修改 AllowedGrantTypes 屬性【可以配置多個 Client】
AllowedGrantTypes = { GrantType.ResourceOwnerPassword, "anonymous" }
using AuthService.CoreLibrary;
using IdentityServer4;
using IdentityServer4.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AuthService.Security
{
public class Clients
{
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = ConfigManager.Configuration["IdentityAuthentication:ClientId"],
ClientName = ConfigManager.Configuration["IdentityAuthentication:ClientName"],
//AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowedGrantTypes =
{
GrantType.ResourceOwnerPassword,
"anonymous"
},
AccessTokenType = AccessTokenType.Reference,
AccessTokenLifetime = Convert.ToInt32(ConfigManager.Configuration["IdentityAuthentication:AccessTokenLifetime"]),
AbsoluteRefreshTokenLifetime = Convert.ToInt32(ConfigManager.Configuration["IdentityAuthentication:AbsoluteRefreshTokenLifetime"]),//30*24*60*60
SlidingRefreshTokenLifetime = Convert.ToInt32(ConfigManager.Configuration["IdentityAuthentication:AbsoluteRefreshTokenLifetime"]),//5*60,
RefreshTokenExpiration = TokenExpiration.Sliding,
UpdateAccessTokenClaimsOnRefresh = true,
AllowOfflineAccess = true,
ClientSecrets = { new Secret(ConfigManager.Configuration["IdentityAuthentication:Secret"].Sha256()) },
AllowedScopes =
{
ConfigManager.Configuration["IdentityAuthentication:Scope"],
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
},
}
new Client
{},
};
}
}
}
In Startup.cs
DI 增加註入對象,注入自定義擴展授權,將其添加到 DI,代碼如下
.AddExtensionGrantValidator<Security.AnonymousGrantValidator>()
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryClients(Security.Clients.GetClients())
.AddInMemoryIdentityResources(Security.IdentityConfig.GetIdentityResources())
.AddInMemoryApiResources(Security.IdentityConfig.GetResources())
.AddProfileService<Security.ProfileService>()
.AddExtensionGrantValidator<Security.AnonymousGrantValidator>() /***** 注入 *****/
.AddResourceOwnerValidator<Security.ResourceOwnerPasswordValidator>();
}
Postman調試
*
*