IdentityServer4 自定義 GrantType 授權模式

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調試

*
*

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章