IdentityServer4 實現自定義 GrantType 授權模式

OAuth 2.0 默認四種授權模式(GrantType):

  • 授權碼模式(authorization_code
  • 簡化模式(implicit
  • 密碼模式(password
  • 客戶端模式(client_credentials

使用 IdentityServer4,我們可以自定義授權模式嗎?答案是可以的,比如我們自定義實現一個 my_sms_auth_code 授權模式

public class Config
{
    /// <summary>
    /// 這個方法返回微服務中的API資源
    /// </summary>
    /// <returns></returns>
    public static IEnumerable<ApiResource> GetApiResources()
    {
        List<ApiResource> resources = new List<ApiResource>();
        resources.Add(new ApiResource("UsersService", "用戶服務API"));
        resources.Add(new ApiResource("ProductService", "產品服務API"));
        return resources;
    }
	
	
    /// <summary>
    /// 這個方法返回我們所有的客戶資源
    /// </summary>
    /// <returns></returns>
    public static IEnumerable<Client> GetClients()
    {
	List<Client> clients = new List<Client>();
        new Client
        {
            ClientId = "client1",
            AllowedGrantTypes = new List<string> { "my_sms_auth_code" }, //一個 Client 可以配置多個 GrantType
            AllowOfflineAccess = true,
            AccessTokenLifetime = 3600 * 6, //6小時
            SlidingRefreshTokenLifetime = 1296000, //15天
            ClientSecrets = { new Secret("123".Sha256()) },
            AllowedScopes = new List<string> { "UsersService" }
        };
	return clients;
    }
}

自定義個類

/// <summary>
/// 我們自定義實現一個anonymous授權模式(匿名訪問)
/// </summary>
public class MyExtensionGrantValidator : IExtensionGrantValidator
{
    public string GrantType => "my_sms_auth_code";

    public async Task ValidateAsync(ExtensionGrantValidationContext context)
    {
        var phone = context.Request.Raw["phone"]; //手機號
        var code = context.Request.Raw["auth_code"];//驗證碼

        var errorvalidationResult = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
        if (string.IsNullOrWhiteSpace(phone) || string.IsNullOrWhiteSpace(code))
        {
            context.Result = errorvalidationResult;
            return;
        }
        if (phone != "18620997009" || code != "1234") //根據手機號碼,驗證驗證碼是否正確
        {
            context.Result = errorvalidationResult;
            return;
        }
        //如果驗證成功了,這裏則是註冊用戶
        //var userid = _userService.Create(phone);
        var userid = 5; //假設上一步創建成功了,並且得到一個用戶id=5;
        if (userid <= 0)
        {
            context.Result = errorvalidationResult;
            return;
        }
        context.Result = new GrantValidationResult(userid.ToString(), GrantType);
    }  
}

3

public void ConfigureServices(IServiceCollection services)
{

    //加載API資源和客戶端資源
    var idResources = new List<IdentityResource>
    {
        new IdentityResources.OpenId(), //必須要添加,否則報無效的scope錯誤 
        new IdentityResources.Profile()
    };
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(idResources)
        .AddInMemoryApiResources(Config.GetApiResources()) //從內存中加載API資源(我們也可設置從數據庫中加載)
        .AddInMemoryClients(Config.GetClients())//從內存中加載客戶端資源
        //.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
        .AddExtensionGrantValidator<MyExtensionGrantValidator>() //這就是我們自定義驗證模式
        .AddProfileService<ProfileService>();
}

請求

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