上篇文章介绍了基于
Ids4
密码授权模式,从使用场景、原理分析、自定义帐户体系集成完整的介绍了密码授权模式的内容,并最后给出了三个思考问题,本篇就针对第一个思考问题详细的讲解下Ids4
是如何生成access_token的,如何验证access_token的有效性,最后我们使用.net webapi来实现一个外部接口(本来想用JAVA来实现的,奈何没学好,就当抛砖引玉吧,有会JAVA的朋友根据我写的案例使用JAVA来实现一个案例)。.netcore项目实战交流群(637326624),有兴趣的朋友可以在群里交流讨论。
一、JWT简介
什么是JWT?
JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。什么时候使用JWT?
1)、认证,这是比较常见的使用场景,只要用户登录过一次系统,之后的请求都会包含签名出来的token,通过token也可以用来实现单点登录。
2)、交换信息,通过使用密钥对来安全的传送信息,可以知道发送者是谁、放置消息是否被篡改。
JWT的结构是什么样的?
JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:
Header
Payload
Signature
Header
header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。
例如:
然后,用Base64对这个JSON编码就得到JWT的第一部分
Payload
JWT的第二部分是payload,它包含声明(要求)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型: registered, public 和 private。
Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
Public claims : 可以随意定义。
Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。
下面是一个例子:
对payload进行Base64编码就得到JWT的第二部分
注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。
Signature
为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。
例如:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。
二、IdentityServer4是如何生成jwt的?
在了解了JWT
的基本概念介绍后,我们要知道JWT
是如何生成的,加密的方式是什么,我们如何使用自己的密钥进行加密。
IdentityServer4的加密方式?
Ids4
目前使用的是RS256
非对称方式,使用私钥进行签名,然后客户端通过公钥进行验签。可能有的人会问,我们在生成Ids4
时,也没有配置证书,为什么也可以运行起来呢?这里就要讲解证书的使用,以及Ids4
使用证书的加密流程。
1、加载证书
Ids4
默认使用临时证书来进行token
的生成,使用代码 .AddDeveloperSigningCredential()
,这里会自动给生成tempkey.rsa
证书文件,所以项目如果使用默认配置的根目录可以查看到此文件,实现代码如下:
这也就可以理解为什么没有配置证书也一样可以使用了。
注意:在生产环境我们最好使用自己配置的证书。
如果我们已经有证书了,可以使用如下代码实现,至于证书是如何生成的,网上资料很多,这里就不介绍了。
.AddSigningCredential(new X509Certificate2(Path.Combine(basePath,"test.pfx"),"123456"));
然后注入证书相关信息,代码如下:
builder.Services.AddSingleton<ISigningCredentialStore>(new DefaultSigningCredentialsStore(credential));builder.Services.AddSingleton<IValidationKeysStore>(new DefaultValidationKeysStore(new[] { credential.Key }));
后面就可以在项目里使用证书的相关操作了,比如加密、验签等。
2、使用证书加密
上篇我介绍了密码授权模式,详细的讲解了流程,当所有信息校验通过,Claim
生成完成后,就开始生成token
了,核心代码如下。
知道了这些原理后,我们就能清楚的知道access_token
都放了那些东西,以及我们可以如何来验证生成的Token
。
三、如何验证access_token的有效性?
知道了如何生成后,最主要的目的还是要直接我们服务端是如何来保护接口安全的,为什么服务端只要加入下代码就能够保护配置的资源呢?
在理解这个前,我们需要了解系统做的验证流程,这里使用一张图可以很好的理解流程了。
看完后是不是豁然开朗?这里就可以很好的理解/.well-known/openid-configuration/jwks
原来就是证书的公钥信息,是通过访问/.well-known/openid-configuration
暴露给所有的客户端使用,安全性是用过非对称加密的原理保证,私钥加密的信息,公钥只能验证,所以也不存在密钥泄漏问题。
虽然只是短短的几句代码,就做了那么多事情,这说明Ids4封装的好,减少了我们很多编码工作。这是有人会问,那如果我们的项目不是.netcore
的,那如何接入到网关呢?
网上有一个Python例子,用 Identity Server 4 (JWKS 端点和 RS256 算法) 来保护 Python web api.
本来准备使用Java来实现,好久没摸已经忘了怎么写了,留给会java的朋友实现吧,原理都是一样。
下面我就已webapi
为例来开发服务端接口,然后使用Ids4来保护接口内容。
新建一个webapi
项目,项目名称Czar.AuthPlatform.WebApi
,为了让输出的结果为json
,我们需要在WebApiConfig
增加config.Formatters.Remove(config.Formatters.XmlFormatter);
代码,然后修改默认的控制器ValuesController
,修改代码如下。
为了保护api安全,我们需要增加一个身份验证过滤器,实现代码如下。
代码非常简洁,就实现了基于Ids4的访问控制,现在我们开始使用PostMan来测试接口地址。
我们直接请求接口地址,返回401未授权。
然后我使用Ids4
生成的access_token
再次测试,可以得到我们预期结果。
为了验证是不是任何地方签发的token
都可以通过验证,我使用其他项目生成的access_token
来测试,发现提示的401未授权,可以达到我们预期结果。
现在就可以开心的使用我们熟悉的webapi
开发我们的接口了,需要验证的地方增加类似[Ids4Auth("http://localhost:6611", "mpc_gateway")]
代码即可。
使用其他语言实现的原理基本一致,就是公钥来验签,只要通过验证证明是允许访问的请求,由于公钥一直不变(除非认证服务器更新了证书),所以我们请求到后可以缓存到本地,这样验签时可以省去每次都获取公钥这步操作。
四、总结
本篇我们介绍了JWT
的基本原理和Ids4
的JWT
实现方式,然后使用.NET webapi
实现了使用Ids4
保护接口,其他语言实现方式一样,这样我们就可以把网关部署后,后端服务使用任何语言开发,然后接入到网关即可。
有了这些知识点,感觉是不是对Ids4
的理解更深入了呢?JWT
确实方便,但是有些特殊场景是我们希望Token
在有效期内通过人工配置的方式立即失效,如果按照现有Ids4
验证方式是没有办法做到,那该如何实现呢?我将会在下一篇来介绍如何实现强制token
失效,敬请期待吧。
相关文章:
AspNetCore中使用Ocelot之 IdentityServer4
Ocelot-基于.NET Core的开源网关实现
.NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权
Swagger如何访问Ocelot中带权限验证的API
Ocelot.JwtAuthorize:一个基于网关的Jwt验证包
.NET Core微服务之基于Ocelot实现API网关服务
.NET Core微服务之基于Ocelot实现API网关服务(续)
.NET微服务体系结构中为什么使用Ocelot实现API网关
Ocelot简易教程(一)之Ocelot是什么
Ocelot简易教程(二)之快速开始1
Ocelot简易教程(二)之快速开始2
Ocelot简易教程(三)之主要特性及路由详解
Ocelot简易教程(四)之请求聚合以及服务发现
Ocelot简易教程(五)之集成IdentityServer认证以及授权
Ocelot简易教程(六)之重写配置文件存储方式并优化响应数据
Ocelot简易教程(七)之配置文件数据库存储插件源码解析
ASP.NET Core中Ocelot的使用:API网关的应用
ASP.NET Core中Ocelot的使用:基于Spring Cloud Netflix Eureka的动态路由
ASP.NET Core中Ocelot的使用:基于服务发现的负载均衡
【.NET Core项目实战-统一认证平台】第一章 功能及架构分析
定制Ocelot来满足需求
【.NET Core项目实战-统一认证平台】第三章 网关篇-数据库存储配置(1)
【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置(2)
【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis
【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权
【.NET Core项目实战-统一认证平台】第七章 网关篇-自定义客户端限流
【.NET Core项目实战-统一认证平台】第八章 授权篇-IdentityServer4源码分析
【.NET Core项目实战-统一认证平台】第九章 授权篇-使用Dapper持久化IdentityServer4
【.NET Core项目实战-统一认证平台】第十章 授权篇-客户端授权
【.NET Core项目实战-统一认证平台】第十一章 授权篇-密码授权模式
原文地址: https://www.cnblogs.com/jackcao/p/10195351.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com