当前位置:网站首页>OAuth2:使用JWT令牌
OAuth2:使用JWT令牌
2022-07-31 14:05:00 【Leon_Jinhai_Sun】
JSON Web Token令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑和自成一体的方式,用于在各方之间作为JSON对象安全地传输信息。这些信息可以被验证和信任,因为它是数字签名的。JWT可以使用密钥(使用HMAC算法)或使用RSA或ECDSA进行公钥/私钥对进行签名。
实际上,我们之前都是携带Token向资源服务器发起请求后,资源服务器由于不知道我们Token的用户信息,所以需要向验证服务器询问此Token的认证信息,这样才能得到Token代表的用户信息,但是各位是否考虑过,如果每次用户请求都去查询用户信息,那么在大量请求下,验证服务器的压力可能会非常的大。而使用JWT之后,Token中会直接保存用户信息,这样资源服务器就不再需要询问验证服务器,自行就可以完成解析,我们的目标是不联系验证服务器就能直接完成验证。
JWT令牌的格式如下:

一个JWT令牌由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终需要传输的字符串。
- 标头:包含一些元数据信息,比如JWT签名所使用的加密算法,还有类型,这里统一都是JWT。
- 有效载荷:包括用户名称、令牌发布时间、过期时间、JWT ID等,当然我们也可以自定义添加字段,我们的用户信息一般都在这里存放。
- 签名:首先需要指定一个密钥,该密钥仅仅保存在服务器中,保证不能让其他用户知道。然后使用Header中指定的算法对Header和Payload进行base64加密之后的结果通过密钥计算哈希值,然后就得出一个签名哈希。这个会用于之后验证内容是否被篡改。
这里还是补充一下一些概念,因为很多东西都是我们之前没有接触过的:
- Base64:就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集(末尾还有1个或多个
=用来凑够字节数),任何的符号都可以转换成这个字符集中的字符,这个转换过程就叫做Base64编码,编码之后会生成只包含上述64个字符的字符串。相反,如果需要原本的内容,我们也可以进行Base64解码,回到原有的样子。
public void test(){
String str = "你们可能不知道只用20万赢到578万是什么概念";
//Base64不只是可以对字符串进行编码,任何byte[]数据都可以,编码结果可以是byte[],也可以是字符串
String encodeStr = Base64.getEncoder().encodeToString(str.getBytes());
System.out.println("Base64编码后的字符串:"+encodeStr);
System.out.println("解码后的字符串:"+new String(Base64.getDecoder().decode(encodeStr)));
}
注意Base64不是加密算法,只是一种信息的编码方式而已。
- 加密算法:加密算法分为对称加密和非对称加密,其中对称加密(Symmetric Cryptography)比较好理解,就像一把锁配了两把钥匙一样,这两把钥匙你和别人都有一把,然后你们直接传递数据,都会把数据用锁给锁上,就算传递的途中有人把数据窃取了,也没办法解密,因为钥匙只有你和对方有,没有钥匙无法进行解密,但是这样有个问题,既然解密的关键在于钥匙本身,那么如果有人不仅窃取了数据,而且对方那边的治安也不好,于是顺手就偷走了钥匙,那你们之间发的数据不就凉凉了吗。
因此,非对称加密(Asymmetric Cryptography)算法出现了,它并不是直接生成一把钥匙,而是生成一个公钥和一个私钥,私钥只能由你保管,而公钥交给对方或是你要发送的任何人都行,现在你需要把数据传给对方,那么就需要使用私钥进行加密,但是,这个数据只能使用对应的公钥进行解密,相反,如果对方需要给你发送数据,那么就需要用公钥进行加密,而数据只能使用私钥进行解密,这样的话就算对方的公钥被窃取,那么别人发给你的数据也没办法解密出来,因为需要私钥才能解密,而只有你才有私钥。
因此,非对称加密的安全性会更高一些,包括HTTPS的隐私信息正是使用非对称加密来保障传输数据的安全(当然HTTPS并不是单纯地使用非对称加密完成的,感兴趣的可以去了解一下)
对称加密和非对称加密都有很多的算法,比如对称加密,就有:DES、IDEA、RC2,非对称加密有:RSA、DAS、ECC
- 不可逆加密算法:常见的不可逆加密算法有MD5, HMAC, SHA-1, SHA-224, SHA-256, SHA-384, 和SHA-512, 其中SHA-224、SHA-256、SHA-384,和SHA-512我们可以统称为SHA2加密算法,SHA加密算法的安全性要比MD5更高,而SHA2加密算法比SHA1的要高,其中SHA后面的数字表示的是加密后的字符串长度,SHA1默认会产生一个160位的信息摘要。经过不可逆加密算法得到的加密结果,是无法解密回去的,也就是说加密出来是什么就是什么了。本质上,其就是一种哈希函数,用于对一段信息产生摘要,以防止被篡改。
实际上这种算法就常常被用作信息摘要计算,同样的数据通过同样的算法计算得到的结果肯定也一样,而如果数据被修改,那么计算的结果肯定就不一样了。
这里我们就可以利用jwt,将我们的Token采用新的方式进行存储:

这里我们使用最简单的一种方式,对称密钥,我们需要对验证服务器进行一些修改:
@Bean
public JwtAccessTokenConverter tokenConverter(){ //Token转换器,将其转换为JWT
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("lbwnb"); //这个是对称密钥,一会资源服务器那边也要指定为这个
return converter;
}
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter converter){ //Token存储方式现在改为JWT存储
return new JwtTokenStore(converter); //传入刚刚定义好的转换器
}@Resource
TokenStore store;
@Resource
JwtAccessTokenConverter converter;
private AuthorizationServerTokenServices serverTokenServices(){ //这里对AuthorizationServerTokenServices进行一下配置
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true); //允许Token刷新
services.setTokenStore(store); //添加刚刚的TokenStore
services.setTokenEnhancer(converter); //添加Token增强,其实就是JwtAccessTokenConverter,增强是添加一些自定义的数据到JWT中
return services;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.tokenServices(serverTokenServices()) //设定为刚刚配置好的AuthorizationServerTokenServices
.userDetailsService(service)
.authenticationManager(manager);
}然后我们就可以重启验证服务器了:

可以看到成功获取了AccessToken,但是这里的格式跟我们之前的格式就大不相同了,因为现在它是JWT令牌,我们可以对其进行一下Base64解码:

可以看到所有的验证信息包含在内,现在我们对资源服务器进行配置:
security:
oauth2:
resource:
jwt:
key-value: lbwnb #注意这里要跟验证服务器的密钥一致,这样算出来的签名才会一致然后启动资源服务器,请求一下接口试试看:

请求成功,得到数据:

注意如果Token有误,那么会得到:

边栏推荐
- Batch大小不一定是2的n次幂!ML资深学者最新结论
- The operator,
- Open Inventor 10.12 重大改进--和谐版
- mysql8, starttime的下一个值作为endtime的上一个值?
- [QNX Hypervisor 2.2用户手册]9.13 rom
- Introduction to the PartImageNet Semantic Part Segmentation dataset
- 【Pytorch】F.softmax()方法说明
- [QNX Hypervisor 2.2 User Manual] 9.13 rom
- Buffer 与 拥塞控制
- Samba 远程命令执行漏洞(CVE-2017-7494)
猜你喜欢

小试牛刀:Go 反射帮我把 Excel 转成 Struct

技能大赛dhcp服务训练题

技能大赛训练题:MS15_034漏洞验证与安全加固

jvm 一之 类加载器

Combination series - there are combinations when there are arrangements

DELL SC compellent 康贝存储系统怎么抓取配置信息

组合系列--有排列就有组合

For enterprises in the digital age, data governance is difficult, but it should be done

All-round visual monitoring of the Istio microservice governance grid (microservice architecture display, resource monitoring, traffic monitoring, link monitoring)

Comparison of Optical Motion Capture and UWB Positioning Technology in Multi-agent Cooperative Control Research
随机推荐
Uniapp WeChat small application reference standard components
Miller_Rabin Miller Rabin probability sieve [template]
Shell script classic case: detecting whether a batch of hosts is alive
Nuget package and upload tutorial
八大排序汇总及其稳定性
ML, DL, CV common problems sorting
Shell项目实战1.系统性能分析
MySQL玩到这种程度,难怪大厂抢着要!
为什么 wireguard-go 高尚而 boringtun 孬种
Install the latest pytorch gpu version
Sliding window method to segment data
Shell脚本经典案例:探测批量主机是否存活
MySQL [subquery]
Node version switching management using NVM
搭建私有的的Nuget包服务器教程
csdn发文助手问题
【Pytorch】F.softmax()方法说明
Comparison of Optical Motion Capture and UWB Positioning Technology in Multi-agent Cooperative Control Research
Introduction to the PartImageNet Semantic Part Segmentation dataset
Small test knife: Go reflection helped me convert Excel to Struct