基于IdentityServer4 实现.NET Core的认证授权

IdentityServer4是什么?

IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现。OpenID Connect 和 OAuth2.0是什么

OpenID Connect:

OpenID Connect由OpenID基金会于2014年发布的一个开放标准, 是建立在OAuth 2.0协议上的一个简单的身份标识层, OpenID Connect 兼容 OAuth 2.0. 实现身份认证(Authentication)
参考资料:https://openid.net/connect/
OpenID Connect文档:https://openid.net/specs/openid-connect-discovery-1_0.html

OAuth2.0:

OAuth2.0是一个开放的工业标准的授权协议(Authorization),它允许用户授权让第三方应用直接访问用户在某一个服务中的特定资源,但不提供给第三方账号及密码信息
参考资料:https://www.cnblogs.com/xiandnc/p/9763121.html
OAuth2.0 文档:https://tools.ietf.org/html/rfc6749#page-73Authentication 和 Authorization的区别


authentication: n. 证明;鉴定;证实
authorization: n. 授权,认可;批准,委任

前者是身份识别,鉴别你是谁;后者是授权许可,告诉你可以做什么。
举个例子:你吭哧吭哧写了一天的代码,急于回家吃上一口媳妇做的热饭。当你走到小区门口的时候你需要刷小区的门禁卡才能进入到小区里面,然后再找到你家在哪一栋楼,几单元几号,然后掏出钥匙开门才能回到家。在这个过程中刷小区的门禁就是认证你是这个小区的人,拿你家的钥匙开门就是授权的过程,如果你的认证不通过,那就不存在授权。uth2.0的原理

我们先来了解一下OAuth2.0中的几个关键概念:

资源所有者(Resource Owner):

  一个能够访问受保护资源的实体。当资源所有者是一个人时,它被称为终端用户

资源服务器(Resource Server):

  托管受保护资源的服务器,能够使用访问令牌接受和响应受保护的资源请求

客户端(Client):

  代表资源所有者和其授权的应用程序来保护资源请求。术语客户端并不意味着任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行)

授权服务器(Authorization Server):

  在成功验证资源所有者并获得授权之后,服务器向客户端发出访问令牌。(授权服务器是用来管理Resource Owner,Resource Server,Client的中间人)

场景:小李想要打印(美图快印)自己三年来发布在新浪微博相册中和女朋友的照片,有没有什么方法他既不告诉工作人员自己的新浪微博用账号和密码又能够方便快捷的把照片给到美图快印呢?(排除存U盘这种手工操作)

 

640?wx_fmt=png

Authorization Server和Resource Server可以使独立的服务提供商,也可以是在一起的,比如例子中新浪微博既作授权服务器也用来存储用户的图片资源。我们可以看到OAuth2解决的问题是:通过Authorization Server可以提供一个访问的凭据(token)给client(美图快印的工作人员),使得client可以在不知道Resource Owner以及Resource Server的用户名和密码的情况下访问到Resource Owner受保护的资源,它是一个完美的中间人。  

OAuth2.0详细内容请参考:https://www.cnblogs.com/xiandnc/p/9763121.html


IdentityServer4能做什么

 640?wx_fmt=png

用户认证服务

  基于OpenID Connect实现的独立的认证服务实现对多平台(web, native, mobile, services)的集中认证

API访问授权

  为各种类型的客户机颁发api访问令牌,例如服务器到服务器、web应用程序、spa和native/mobile程序

联合身份认证

  支持外部身份提供者,如Azure Active Directory、Google、Facebook等

定制化的实现

  IdentityServer4的许多方面可以定制以满足您的需要,因为它是一个框架,而不是SaaS服务,所以可以通过编写代码来调整实现,以适应不同的场景

成熟的开原方案

  使用许可的Apache2开源协议,允许在其之上构建商业产品,也作为.NET基金会支持的项目 (https://dotnetfoundation.org/projects?type=project&ps=10&pn=6)

提供免费的商业支持

  官方可以对使用者提供部分的免费商业支持


IdentityServer4定义的基本术语

 640?wx_fmt=png

IdentityServer

  身份认证服务器是一个实现了OpenID Connect和OAuth 2.0协议的身份提供者,它负责向客户端发布安全令牌

User

  使用注册客户端访问资源的用户

Client

        客户端从标识服务器请求令牌,要么用于认证用户(请求身份令牌),要么用于访问资源(请求访问令牌) 
        客户端必须首先在身份服务器上注册,然后才能请求令牌 
       这里的客户端可以是web应用程序、native mobile, desktop applications, SPA 等程序


Resource
  资源是你想要用身份认证服务器保护的东西,如:用户的身份数据或api 
  每个资源都有一个惟一的名称,客户端使用这个名称来指定他们想要访问的资源 
  关于用户的身份数据标识(也称为claim),例如姓名或电子邮件地址


Identity Token
  身份令牌代表身份验证过程的结果


Access Token
  访问令牌授权客户端以允许访问哪些API资源,访问令牌包含客户端和用户的信息

 


IdentityServer4的简单示例

 我们先来看一个简单的例子,我们有三个API ,Order, Product, Inventory,我们利用IdentityServer4来实现对着三个API的认证和授权。首先我们需要一个实现认证和授权的服务,然后外部要想访问我们的API就必须通过统一的认证和授权服务的任何才可以,否则就是返回401: UnAuthorized ,未经授权的访问。我们既可以将身份信息存储到内存中,也可以将其持久化到数据库中,此处我们使用内存模式快速的演示实现(示例代码中也支持存储到DB中,使用SqlLite + EF Core)

首先我们需要安装IdentityServer4的Nuget包,然后在ConfigureServices方法中添加如下代码来初始化需要保护的API资源信息,代码如下:

 


public void ConfigureServices(IServiceCollection services)
        {
            // config data in memory
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(InitMemoryData.GetApiResources())
                .AddInMemoryClients(InitMemoryData.GetClients())
                .AddTestUsers(InitMemoryData.GetUsers());
            // config in DB
            //services.AddDbContext<IdentityServerDbContext>(options =>
            //                            options.UseSqlite(sqliteConnection));
        }

 InitMemoryData 中的配置信息如下:


// scopes define the API resources in your system
       public static IEnumerable<ApiResource> GetApiResources()
       {
           return new List<ApiResource>
           {
               new ApiResource("inventoryapi""this is inventory api"),
               new ApiResource("orderapi""this is order api"),
               new ApiResource("productapi""this is product api")
           };
       }
       // clients want to access resources (aka scopes)
       public static IEnumerable<Client> GetClients()
       {
           // client credentials client
           return new List<Client>
           {
               new Client
               {
                   ClientId = "inventory",
                   AllowedGrantTypes = GrantTypes.ClientCredentials,
                   ClientSecrets =
                   {
                       new Secret("inventorysecret".Sha256())
                   },
                   AllowedScopes = { "inventoryapi" }
               },
                new Client
               {
                   ClientId = "order",
                   AllowedGrantTypes = GrantTypes.ClientCredentials,
                   ClientSecrets =
                   {
                       new Secret("ordersecret".Sha256())
                   },
                   AllowedScopes = { "orderapi" }
               },
                new Client
               {
                   ClientId = "product",
                   AllowedGrantTypes = GrantTypes.ClientCredentials,
                   ClientSecrets =
                   {
                       new Secret("productsecret".Sha256())
                   },
                   AllowedScopes = { "productapi" }
               }
           };
       }

我们给IdentityServer4设置启动端口5000,认证服务的地址就是:http://localhost:5000 

然后认证Server端的代码就好了,接下来我们需要在API添加授权服务的配置,配置都很类似,我们以OrderAPI为例: 


// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ApiName = "orderapi";
                });
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();
            app.UseMvc();
        }

这里我们配置的Authority地址就是认证授权的地址,AddAuthentication中的Bearer是Jwt Token的一种,具体可参考文章:https://www.cnblogs.com/Leo_wl/p/7792046.html

在controller中添加简单代码来返回API的信息:


[Route("[controller]")]
    [Authorize]
    public class OrderController : ControllerBase
    {
        // GET api/order
        [HttpGet]
        public IActionResult Get()
        {
            var userIdentitys = from c in User.Claims
                                select new UserIdentity
                                {
                                    Type = c.Type,
                                    Value = c.Value
                                };
            var result = new UserIdentityModel()
            {
                Description = "Access user order api successfully",
                UserIdentitys = userIdentitys.ToList()
            };
            return new JsonResult(result);
        }
    }

640?wx_fmt=gif

设置当前API的端口为:5002

Product和Inventory中的配置和这个类似,端口信息以此设置为5001,5003,一切就绪,让我们来测试一下结果:

启动IdentotyServer,以及三个API,我们使用Postman来请求api,下面站点就是IdentityServer的页面了:

640?wx_fmt=png

接着我们来直接访问OrderAPI就会发现返回 401 ,这说明目前我们的API已经受保护了,没有认证服务颁发的token,是直接访问不了的。

640?wx_fmt=png

我们输入地址:http://localhost:5000/.well-known/openid-configuration  可以查看我们当前认证授权服务的配置信息:

640?wx_fmt=png

 

现在还差一步就可以访问我们的OrderAPI了,那就是:客户端传入必要的信息给认证服务,生成一定格式的token,然后携带着这个token来访问我们的服务 

 640?wx_fmt=png

传入的三个参数分别是grant_type , client_sercret, client_id这几个参数分别代表了我们申请token时的授权方式是客户端授权,密匙,clientid信息。我们在前面介绍过IdentityServer4是对OAuth2.0的实现,所以具体参数的含义请参考之前OAuth2.0文章中的详细介绍

https://www.cnblogs.com/xiandnc/p/9763121.html

此时我们可以看到认证服务给我们返回了有效token,指定过期时间3600s ,token的类型是Bearer,然后我们再携带这这个token去访问服务试试看:

640?wx_fmt=png

 

我们可以看到此时API 返回了我们期待的正确结果,如果在1小时后再携带着这个token去访问API就会提示token已过期,需要重新生成才能够继续访问。看完这个例子是不是很简单,很清爽呢

例子参考代码:https://github.com/KenWang007/IdentityServer4Demo

原文地址:https://www.cnblogs.com/xiandnc/p/10150814.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[COCI 2018#5]Parametriziran

这道题呢&#xff01; 算了&#xff0c;不要让这玩意儿活着祸害众生吧&#xff01;让我们来拯救苍生于苦海之中&#xff01;&#xff01; 骚话连篇ing 题目 由小写英文字母和问号组成的字符串成为参数化单词&#xff08;例如&#xff1a;??cd,bcd,??&#xff09;。如果两…

P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)

传送门 文章目录解析解析 很显然&#xff0c;让马走的话状态记录和转移都会比较复杂 所以转化成让空位跳会更好做一点 但这不是重点 初看本题&#xff0c;其实第一感觉是bfs 但是状态数理论上最差可以达到815&#xff0c;&#xff08;当然基本不可能跑满&#xff09;&#xff…

NumSharp v0.6 科学计算库发布,新增 LAPACK 的线性库支持

NumSharp&#xff08;Numerical .NET&#xff09;可以说是C&#xff03;中的科学计算库。 它是用C&#xff03;编写的&#xff0c;符合.netstandard 2.0库标准。 它的目标是让.NET开发人员使用NumPy的语法编写机器学习代码&#xff0c;从而最大限度地借鉴现有大量在python代码的…

[COCI] Zamjena

连这种模拟题都能。。。orz ex&#xff0c;太恶心了&#xff01; 驰骋坑底这么久了&#xff0c;我明白了 开始吧&#xff01;我发誓&#xff0c;这个超级兵&#xff0c;我就算用小书包平A都要A了它 题目 Vlatko喜欢使用整数数组&#xff0c;他在一张纸上写下了两个数组&…

P2601 [ZJOI2009]对称的正方形(二维哈希)(二分)

洛谷传送门 文章目录题目描述解析代码题目描述 解析 做三个hash 分一下正方形边长的奇偶性 然后枚举中心点&#xff0c;二分边长即可 有点类似模拟赛那道红十字的题 我一开始觉得分奇偶好麻烦啊 为什么不直接枚举左上方的点二分呢&#xff1f;awa 很遗憾的是… 那样答案就没有…

初赛—错题集

计算机基础知识 LAN&#xff1a;局域网&#xff0c;WAN&#xff1a;广域网&#xff0c;MAN&#xff1a;城域网 汇编语言是(依赖于具体计算机)的低级程序设计语言 计算机操作的最小时间单位是(时钟周期)。 注意所需空间需要 \(\div 8\) &#xff01;&#xff01;&#xff01;…

.NET Core 和 DevOps

关键要点无论你目前使用什么样的技术栈&#xff0c;DevOps 都是值得一试的。闭源、专有软件和构建过程与 DevOps 实践不兼容。.NET Core 是开源的&#xff0c;是基于 DevOps 构思和构建的。.NET Core CLI 和 Roslyn API 让整个交付流程变得更加开放&#xff0c;且具有更强的适应…

Message Decoding密码翻译

这是一道模拟题ex 其实每一道模拟题都很“简单”&#xff0c; 这道题就是难在读英文题&#xff01;处理输入&#xff01; 真的我竟然花了几个小时就只是为了看懂样例&#xff01;&#xff01;orz 题目大意 考虑下面的01串序列&#xff1a; 0&#xff0c;00&#xff0c;01…

.NET Core开发日志——结构化日志

在.NET生态圈中&#xff0c;最早被广泛使用的日志库可能是派生自Java世界里的Apache log4net。而其后来者&#xff0c;莫过于NLog。Nlog与log4net相比&#xff0c;有一项较显著的优势&#xff0c;它支持结构化日志。结构化日志&#xff0c;也被称为语义化日志。其作用有二&…

YBTOJ 特殊数列(哈希表)

文章目录题目描述解析代码题目描述 解析 应该是哈希表板子题了 选一个1e6左右的质数进行处理即可 其实本质就是链前 没啥特别新鲜的 为什么要写呢&#xff1f; 因为这个东西很早之前看的时候完全没有看懂。。。 代码 #include<bits/stdc.h> using namespace std; #def…

Strange Definition CodeForces - 1471D

题意&#xff1a; 定义数字 x 和 y 是“相邻”的当且仅当 lcm(x,y)/gcd(x,y) 是一个平方数。 给定一个长度为 n 的数组 a。 每过一秒&#xff0c;数组 a 会发生变化&#xff1a;ai 会变成数组 a 中与其“相邻”的所有数字的乘积。 定义 di 为数组 a 中与 ai “相邻” 的数字个…

学习三分 (概念 + 模板 + 例题:曲线)

这好像是我第一次尝试写一个新知识入门 而不是习题解 文章目录三分概念模板例题&#xff1a;曲线题目题解代码实现三分概念 我们都知道&#xff0c;二分是在一个单调函数&#xff08;即一次函数&#xff09;上通过每次查找折半的方式&#xff0c;对答案进行搜索查找。那么&am…

迎元旦,庆surging 1.0发布

一位摄影程序员的独白每个人都有爱好&#xff0c;都有释放压力的活动&#xff0c;而我也不例外&#xff0c;我除了每天上班&#xff0c;周末就会约一群好友去拍妹子&#xff0c;成家后&#xff0c;就改为拍虫子&#xff0c;一拍就到了30岁&#xff0c;到了30岁就感觉到了中年的…

YBTOJ:求好元素(哈希表)

文章目录题目描述解析代码题目描述 解析 如果枚举m,n,p的话是n3的 会超时 但我们注意到右边查询只有O(n) 这就很不平衡 所以考虑把p移到右边&#xff0c;预处理枚举m、n存到哈希表中 查询枚举i、p 这样就把复杂度均摊降到了n2 但是本题数据较强 所以我们得保证哈希表的单词查询…

Strange Shuffle CodeForces - 1471E(交互题)

交互题 这类型不同于普通的题。 可以理解为有个问题需要你解决&#xff0c;你通过输入某些东西表示你要问系统的问题&#xff0c;这时系统会回答你的问题。在代码中的回答方式就是会输入某个东西就是系统给你的答案&#xff0c;通过这些信息你可以得到问题的解你是不可以自己测…

学习KMP (概念 + 模板 + 例题: 子串查找)

我又回来了&#xff0c;感jio这几天有点勤啊&#xff01;&#xff01; 这一次我带着KMP来了&#xff0c; 文章目录KMP介绍模板例题&#xff1a; 子串查找题目暴力题解KMP题解代码实现KMP介绍 KMP&#xff0c;即 Knuth-Morris-Pratt 字符串查找算法&#xff0c;由Donald Knuth…

直播预告 - 博时基金DevOps体系建设和自动化测试分享

最近几年&#xff0c;基金行业发展比较快&#xff0c;业务范围从传统公募到大资管&#xff0c;业务地域从中国大陆到全球化&#xff0c;在互联网金融浪潮中扮演了重要角色&#xff0c;金融科技又带来新的挑战和机遇。据毕马威2014年研究报告显示&#xff0c;由于新技术、人口变…

YBTOJ:公共子串(KMP)

文章目录题目描述解析代码题目描述 解析 我的做法是二分答案&#xff0c;暴力枚举子串&#xff0c;对其他的字符串进行KMP。 复杂度logL*L2 没有一次AC&#xff0c;因为忘记了字符串清零&#xff01;&#xff0c;否则它会和上次二分的字符串没被覆盖到的部分连在一起。 之前遇…

Asp.Net Core + Docker 搭建

一、Docker安装&#xff08;1&#xff09;机器准备 本次实验&#xff0c;我是在Win10上,使用Vmware Workstation虚拟机安装的Ubuntu 18.04.l LTS版本进行搭建。&#xff08;2&#xff09;安装Docker# yum install docker注意:如果提示未安装yum 使用命令:apt-get install yum&a…

数数字

今天中午1小时&#xff0c;定时两道&#xff0c;我就知道自己的太阳降落了。。。orz 文章目录题目题解代码实现题目 PB 带来了若干只蒟蒻。 众所周知&#xff0c;NTF 是数论学会的会长&#xff0c;于是 PB 准备用数字击败 NTF&#xff0c;以证明 PB 比 NTF 更强。 于是 PB 准…