做h5小程序的网站,搜索引擎营销案例,为企业做网站还有前途吗,创建全国文明城市方案一.前言本文为系列补坑之作#xff0c;拖了许久决定先把坑填完。下文演示所用代码采用的 IdentityServer4 版本为 2.3.0#xff0c;由于时间推移可能以后的版本会有一些改动#xff0c;请参考查看#xff0c;文末附上Demo代码。本文所诉Token如无特殊说明皆为 JWT Token。众… 一.前言本文为系列补坑之作拖了许久决定先把坑填完。下文演示所用代码采用的 IdentityServer4 版本为 2.3.0由于时间推移可能以后的版本会有一些改动请参考查看文末附上Demo代码。本文所诉Token如无特殊说明皆为 JWT Token。众所周知 JWT Token 由三部分组成第一部分 Header包含 keyid、签名算法、Token类型第二部分 Payload 包含 Token 的信息主体如授权时间、过期时间、颁发者、身份唯一标识等等第三部分是Token的签名。我们对一个 Token 进行解码观察其中 Payload 部分你将会发现一个 iss 字段那么它代表什么呢它又有什么作用呢请看后文分解。二. Issuer 的前世今生iss 是 OpenId Connect后文简称OIDC协议中定义的一个字段其全称为 “Issuer Identifier”中文意思就是颁发者身份标识表示 Token 颁发者的唯一标识一般是一个 http(s) url如 https://www.baidu.com。在 Token 的验证过程中会将它作为验证的一个阶段如无法匹配将会造成验证失败最后返回 HTTP 401。三. Issuer 的验证流程分析JWT的验证是去中心化的验证实际这个验证过程是发生在API资源的除了必要的从 IdentityServer4 获取元数据获取后会缓存不用重复获取比如获取公钥用于验证签名是不会再去交互的详细介绍https://www.cnblogs.com/stulzq/p/9226059.html。那么我们就从 API 资源作为入口开始分析。我们在 API 资源的配置认证的代码如下一个携带 Token 的请求从认证中间件到最终验证 Issuer 的逻辑如下图懒得画流程图了直接做个gif。请看原文最终验证 Issuer 的代码由源码分析可以获得几个结论1.验证 Token 必定会验证 Issuer如果 Issuer 验证失败那么表示则整个 Token 的验证结果就是失败。Issuer 默认从 IdentityServer4 的 Discovery Endpoint/.well-known/openid-configuration获取Issuer3.Issuer 可以自定义并且可以设置一个列表如果手动设置了会覆盖默认值4.Issuer 验证逻辑默认只验证是否相等即 Token 携带的 Issuer 是否与 设置的 Issuer 值相等。5.Issuer 验证逻辑可以自定义6.Issuer 的验证可以关闭以上设置如无特殊需求直接使用默认值即可不需要额外设置。关于以上结论的在代码API资源中的实现四.如何设置 Token 的 Issuer第三节讲的是 Issuer 验证时有效 Issuer 的设置本节讲的是 设置 Token 的 IssuerToken携带的 Issuer 与API资源设置的有效 Issuer 进行验证匹配完成整个流程这里提一下避免搞混。设置 Token 的 Issuer 需要在 IdentityServer4 设置。在 Startup 里中设置services.AddIdentityServer(optionoption.IssuerUrihttps://www.baidu.com)此值必须是一个 http(s) url。验证是否生效1.访问 Discovery Endpoint/.well-known/openid-configuration2.对Token解码查看 iss 字段如果在 IdentityServer4 设置此值默认情况下所有API资源都会获取此值作为默认有效Issuer。如果你自定义了 Issuer在使用 Client 访问时会出现 Issuer 与 Authority 不匹配的错误是因为Client在默认情况下作了限制关闭即可var client new HttpClient();var disco await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest(){Address http://localhost:5000 ,Policy new DiscoveryPolicy(){ValidateIssuerName false}});五.默认值问题如果没有手动设置 IdentityServer4 IssuerUri 值那么它默认会取你访问 IdentityServer4 时的 Host下面举例说明。首先修改 IdentityServer4 项目的监听地址使其能够通过局域网IP访问然后分别通过 localhost 和 局域网ip 访问 Discovery Endpoint观察 Issuer 的值localhost:局域网IP看出差异了吧这一点需要注意下一节将会讲一下这个引发的问题。六.Issuer 默认值问题可能出现的场景及解决这种情况一般出现在 IdentityServer4 经过了一层或多层代理比如 Nginx反代、网关等外网地址经过代理传递到了 IdentityServer4如果直接通过外网请求的 Token Endpoint/connect/token 生成的 Token那么这个 Token 携带的 iss 地址将会是外网地址正常情况下Host是会经过代理传过来的如果你不配置传过来那么就没有这个问题那么你的后端服务获取的地址与预期肯定有差别不推荐这种做法。但是本地API资源与IdentityServer4在同一台服务器或者同一个局域网与IdentityServer4交互的地址Authority肯定会配成localhost 或者是局域网地址如果你这里配置成外网地址那么你可以不继续往下看了内部交互还要走外部网络严重不推荐甚至是禁止此种做法。上图的架构即便是把 Gateway、IdentityServer、Basket服务API资源放在一台机器上也是一样的道理都会出现这种情况其原因就是如果 IdentityServer 不设置 Issuer就会取你访问IdentityServer时的Host作为Issuer外网进来的Host地址和你内部交互的不一样就造成了这个问题解决办法就是在 IdentityServer 手动指定一个 Issuer 即可解决第四节取消掉它的默认取Host的机制不管你怎么访问IdentityServer返回的Issuer都是一个地址。七.结束Demo:https://github.com/stulzq/IdentityServer4.Samples/tree/master/Practice/03_Issuer参考资料OIDCOpenId Connect身份认证授权核心部分 by blackheart.原文地址https://www.cnblogs.com/stulzq/p/10339024.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com