asp.net core IdentityServer4 實現 resource owner password credentials(密碼憑證)

前言

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

本章主要介紹密碼模式(resource owner password credentials),OAuth2.0資源所有者密碼授權功能允許客戶端將用戶名和密碼發送到令牌服務,並獲得該用戶的訪問令牌.

認證步驟:

  • 用戶將用戶名密碼提供給客戶端
  • 客戶端再將用戶名密碼發送給授權服務器,請求令牌
  • 授權服務器確定判斷信息是否有誤,返回給客戶端令牌

創建授權服務器

創建一個API項目工程,我這邊以端口5000的形式進行後面的講解.

Package

PM> Install-package IdentityServer4 -version 2.5.3

創建一個類Config(配置要保護的資源,和可以訪問的API的客戶端服務器)

   public class Config
    {
        /// <summary>
        ///     定義要保護的資源
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiResources() {
            return new List<ApiResource>
            {
               new ApiResource("api1","MyApi")
            };
        }
        /// <summary>
        ///     定義授權客戶端
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients() {
            return new List<Client>
            {
                new Client(){ 
                    ClientId="client",
                    AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
                    ClientSecrets=
                    {
                      new Secret("secret".Sha256())
                    },
                    AllowedScopes={ "api1",IdentityServerConstants.StandardScopes.OfflineAccess //如果要獲取refresh_tokens ,必須在scopes中加上OfflineAccess
                    },
                    AllowOfflineAccess=true// 主要刷新refresh_token,
        
                }
            };
        }
    }

此處AllowedGrantTypes需要設置爲ResourceOwnerPassword(密碼憑證).

配置Startup

再走到ConfigureServices方法注入IdentityServer4服務

   public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();//注入自定義登錄驗證

        }

IdentityServer4默認提供了兩種證書加密配置
AddDeveloperSigningCredential AddTemporarySigningCredential
添加內存ApiResourceAddInMemoryApiResources
添加內存Client AddInMemoryClients
添加自定義登錄驗證AddResourceOwnerValidator

自定義用戶驗證
    public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {
        public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            if (context.UserName == "test" && context.Password == "test")
            {
                context.Result = new GrantValidationResult(
                 subject: context.UserName,
                 authenticationMethod: OidcConstants.AuthenticationMethods.Password);
            }
            else
            {
                //驗證失敗
                context.Result = new GrantValidationResult(
                    TokenRequestErrors.InvalidGrant,
                    "invalid custom credential"
                    );
            }
            return Task.FromResult(0);
        }
    }

在Configure方法中添加IdentityServer4服務中間件

app.UseIdentityServer();

創建ApiResource

創建一個客戶端項目,這邊我將端口設置爲5001

Package

PM> Install-package IdentityServer4 -version 2.5.3

配置Startup

在ConfigureServices添加認證服務器地址

      public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddAuthentication("Bearer")
              .AddIdentityServerAuthentication(options =>
              {
                  options.Authority = "http://localhost:5000";//授權服務器地址
                   options.RequireHttpsMetadata = false;//不需要https    
                   options.ApiName = "api1";
              });
        }

在Configure方法中添加認證服務中間件

app.UseAuthentication();

Run

在客戶端程序values控制器上面增加[Authorize]

直接訪問資源服務器http://localhost:5001/api/values

1098068-20190928102744659-14289503.png

code 401

啓動授權服務器

http://localhost:5000/.well-known/openid-configuration

發現端點可通過/.well-known/openid-configuration

1098068-20190928102801836-1205007954.png

獲取token

這邊我用postman進行測試

1098068-20190928102834736-1968349689.png

code 200

access_token我們獲取到了,再拿着token通過postman請求資源程序,

1098068-20190928103123183-325677549.png

code 200
成功了

refresh_token

獲取請求授權接口後會返回access_token expires
_in 等內容,expires_in是有效期(s),當然我們可以自定義有效期,access_token失效後用戶需要重新授權,client才能拿到新的access_token.但是有了refresh_token後,client檢測到token失效後可以直接通過refresh_token向授權服務器申請新的token,當然refresh_token也是有有效期的。
AbsoluteRefreshTokenLifetime的默認有效期爲2592000秒/30天。SlidingRefreshTokenLifetime的默認有效期爲1296000秒/15天。

在認證服務器中我再scopes加上了OfflineAccess
IdentityServerConstants.StandardScopes.OfflineAccess //如果要獲取refresh_tokens ,必須在scopes中加上OfflineAccess

獲取refresh_token

1098068-20190928102905777-1878266890.png

通過refresh_token再去獲取access_token

1098068-20190928102914115-135515635.png

通過postman請求獲取資源

1098068-20190928102928538-2091233755.png

概要

示例地址https://github.com/fhcodegit/IdentityServer4.Samples

發佈了55 篇原創文章 · 獲贊 57 · 訪問量 4651
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章