IdentityServer4 实现自定义 GrantType 授权模式

OAuth 2.0 默认四种授权模式(GrantType)

  • 授权码模式(authorization_code)
  • 简化模式(implicit)
  • 密码模式(password)
  • 客户端模式(client_credentials)

1.使用 IdentityServer4,我们可以自定义授权模式

例如:自定义sms_auth_code 授权模式

using IdentityServer4;
using IdentityServer4.Models;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace User.Identity
{
    public  class IdentityServerConfig
    {


        /// <summary>
        /// Client
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients() 
        {
            return new List<Client>
            {
                //new Client{
                //    ClientId = "iphone",
                //    ClientSecrets = new List<Secret>
                //    {
                //        new Secret("secret".Sha256())
                //    },
                //    RefreshTokenExpiration = TokenExpiration.Sliding,
                //    AllowOfflineAccess = true,
                //    RequireClientSecret = false,
                //    AllowedGrantTypes = new List<string>{ "sms_auth_code"},
                //    AlwaysIncludeUserClaimsInIdToken = true,
                //    AllowedScopes = new List<string>{
                //        "finbook_api",
                //        IdentityServerConstants.StandardScopes.OpenId,
                //        IdentityServerConstants.StandardScopes.Profile,
                //        IdentityServerConstants.StandardScopes.OfflineAccess
                //    }

                //}

                new Client{ 
                    ClientId = "android",
                    ClientSecrets = new List<Secret>{ new Secret("secret".Sha256())},
                    AllowedGrantTypes = new List<string>{ "sms_auth_code" },
                    AllowedScopes = { "user_api" }
                }
            };
        }


        /// <summary>
        /// Identity Resources
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<IdentityResource> GetIdentityResources() 
        {
            return new List<IdentityResource> {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile()
            };  
        }


        /// <summary>
        /// API Resource
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource> {
                new ApiResource("user_api","用户API")
            };
        
        }
    }
}

2.自定义类需要继承using IdentityServer4.Validation下的IExtensionGrantValidator接口

using IdentityServer4.Models;
using IdentityServer4.Services;
using IdentityServer4.Validation;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using User.Identity.Services;

namespace User.Identity.Authentication
{
    public class SmsAuthCodeValidator : IExtensionGrantValidator
    {
        public string GrantType => "sms_auth_code";

        public readonly IAuthCodeService _authCodeService;
        public readonly IUserService _userService;

        public SmsAuthCodeValidator(IAuthCodeService authCodeService, IUserService userService) {
            _authCodeService = authCodeService;
            _userService = userService;
        }

        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            var phone = context.Request.Raw["phone"];
            var authcode = context.Request.Raw["sms_auth_code"];
            var errorValidateResult = new GrantValidationResult(TokenRequestErrors.InvalidGrant);

            if (!string.IsNullOrEmpty(phone) || !string.IsNullOrEmpty(authcode))
            {
                context.Result = errorValidateResult;
                return;
            }

            //校验验证码
            if (!_authCodeService.Validate(phone,authcode))
            {
                context.Result = errorValidateResult;
                return;
            }

            //校验手机号是否存在,
            var userid =await _userService.CheckOrCreateAsync(phone);
            if (userid<=0)
            {
                context.Result = errorValidateResult;
                return;
            }

            context.Result =  new GrantValidationResult(userid.ToString(),GrantType);

        }
    }
}

3.在Startup.csConfiguration的配置如下

public void ConfigureServices(IServiceCollection services)
        {
            //配置Identity Server
            var builder = services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources())
                .AddInMemoryApiResources(IdentityServerConfig.GetApiResources())
                .AddInMemoryClients(IdentityServerConfig.GetClients())
                .AddExtensionGrantValidator<SmsAuthCodeValidator>()//IdentityServer自定义验证
                ;


            //依赖注入
            services.AddScoped<IAuthCodeService, AuthCodeService>()
                .AddScoped<IUserService, UserService>()
                .AddSingleton<HttpClient>();

            services.AddControllers();
        }

4.PostMan 请求

image

posted @ 2020-09-10 17:53  无敌土豆  阅读(728)  评论(1编辑  收藏  举报