ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

IdentityServer4实战:持久化 Resource

2021-04-10 08:32:38  阅读:174  来源: 互联网

标签:实战 Resource name List result ApiScope var new IdentityServer4


前言

在前几篇的学习中,我们定义的 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

 

标签:实战,Resource,name,List,result,ApiScope,var,new,IdentityServer4
来源: https://www.cnblogs.com/limitcode/p/14639521.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有