IdentityServer4實戰:持久化 Resource


前言

在前幾篇的學習中,我們定義的 ApiResource、ApiScope、IdentityResource 都是存儲在內存中的,通過 AddInMemoryApiScopes(Startup.GetApiScopes())、AddInMemoryIdentityResources(Startup.GetIdentityResources())、 AddInMemoryApiResources(Startup.GetApiResources()) 的方式注入到 IDS4 的服務中。本篇我們學習如何使用數據庫或其他持久化方法存儲和讀取 Resource 。

IdentityServer4 中 Resource 概念

在 IdentityServer4 中一共有3種資源類型:IdentityResource、ApiResource、ApiScope,定義這些資源的名稱必須是唯一的,不可重復。

IdentityResource

身份資源,表示關於用戶的聲明,如用戶ID、顯示名、電子郵件地址等。

ApiResource

對 ApiScope 高層分組(歸類)。當 API 資源變大時,使用 ApiScope 作用域列表可能不可行。通常需要引入某種名稱空間來組織作用域名稱,可能還希望將它們分組在一起,並獲得一些更高級的構造,如訪問令牌中的受眾聲明。如:多個資源應該支持相同的作用域名稱,但是有時您顯式地希望將一個作用域隔離到某個資源。 在IdentityServer中,ApiResource類允許一些額外的組織

ApiScope

資源作用域。

IResourceStore 接口

IDS4 為開發者定義了一個 IResourceStore 接口,實現該接口即可做自己的 Resource 持久化存儲和讀取。

CustomerResourceStore 實現

新建 CustomerResourceStore 類,實現 IResourceStore 接口,寫我們自己的資源查找規則。

為了簡單,筆者使用的 Resource 全部是已賦值好的內容,筆友可以通過數據庫或其他持久化介質獲取 Resource。

FindIdentityResourcesByScopeNameAsync

/// <summary>
        /// 身份資源
        /// </summary>
        private readonly List<IdentityResource> identityResources = new List<IdentityResource> {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile()
        };

 

/// <summary>
        /// 通過 名稱 查找符合要求的 IdentityResources
        /// </summary>
        /// <param name="scopeNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
        {
            var result = new List<IdentityResource>();

            foreach (var name in scopeNames)
            {
                if (identityResources.Count(t => t.Name == name) > 0)
                {
                    result.Add(identityResources.First(t => t.Name == name));
                }
            }

            return result;
        }

 

FindApiResourcesByNameAsync

/// <summary>
        /// ApiResource 資源
        /// </summary>
        private readonly List<ApiResource> apiResources = new List<ApiResource> {
            new ApiResource("admin", "用戶管理"){
                Scopes = { "user.list" , "user.delete" }
            },
            new ApiResource("article", "文章管理"){
                Scopes = { "article.list" , "article.delete" }
            },
        };

 

/// <summary>
        /// 通過 名稱 查找符合要求的 ApiResources
        /// </summary>
        /// <param name="apiResourceNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
        {
            var result = new List<ApiResource>();

            foreach (var name in apiResourceNames)
            {
                if (apiResources.Count(t=>t.Name== name) > 0)
                {
                    result.Add(apiResources.First(t => t.Name == name));
                }
            }

            return result;
        }

 

FindApiScopesByNameAsync

/// <summary>
        /// ApiScope 資源
        /// </summary>
        private readonly List<ApiScope> apiScopeResources = new List<ApiScope> {
            new ApiScope("article.list", "文章-查看"),
            new ApiScope("article.delete", "文章-刪除"),

            new ApiScope("user.list", "用戶-查看"),
            new ApiScope("user.delete", "部門-刪除"),
        };

 

/// <summary>
        /// 通過 名稱 查找符合要求的 ApiScopes
        /// </summary>
        /// <param name="scopeNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
        {
            var result = new List<ApiScope>();

            foreach (var name in scopeNames)
            {
                if (apiScopeResources.Count(t => t.Name == name) > 0)
                {
                    result.Add(apiScopeResources.First(t => t.Name == name));
                }
            }

            return result;
        }

 

FindApiResourcesByScopeNameAsync

/// <summary>
        /// 通過 作用域名稱 查找符合要求的 ApiResources
        /// </summary>
        /// <param name="scopeNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
        {
            var result = new List<ApiResource>();

            foreach (var name in scopeNames)
            {
                foreach (var apiResource in apiResources)
                {
                    if (apiResource.Scopes.Contains(name) && result.Count(t=>t.Name == name) ==0)
                    {
                        result.Add(apiResource);
                    }
                }
            }

            return result;
        }

 

GetAllResourcesAsync

/// <summary>
        /// 返回所有的資源
        /// </summary>
        /// <returns></returns>
        public  async Task<Resources> GetAllResourcesAsync()
        {
            return new Resources(identityResources, apiResources, apiScopeResources);
        }

 

修改 Client 的 AllowedScopes

new Client
                    {
                        ClientId = "client2",

                        //  用戶名 密碼 模式
                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

                        // 用於認證的密碼
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
                        // 客戶端有權訪問的范圍(Scopes)
                        AllowedScopes = {
                            "openid", 
                            "profile" ,
                            "article.list" ,
                            "article.delete" ,
                            "user.list" ,
                            "user.delete"
                        }
                    }

 

刪除注入的內存資源服務

PostMan 測試

 

 

 

本文轉載自:https://limitcode.com/detail/606f012fd9118c3cd416879a.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM