文章目录
引言
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
JWT的三个特点
自包含:
包含有意义的信息,令牌里面是有信息的,拿到这个令牌之后直接解析令牌就可以知道里边的信息是什么,不需要再去存储里边读一个东西
密签:
密签是一种签名而不是加密,JWT是一种开放的标准,发出去的秘钥信息是按照标准方式生成的,所有人是可以看到里边的信息,所以不要把敏感的信息放进去
签名:
防止别人篡改,发出去的令牌,如果里边信息被改变了,你是可以知道的
加密:
里边的信息别人不能被破解
可扩展:
可以自定义放进去的东西
默认方式生成一个令牌,因为是用UUID
的方式,最后得到一个没有意义的串,这种机制的特点是:依赖一个存储,一旦存储出现问题了,这个串就没有任何意义了
JWT组成
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE1MTY3MjY4MTMsImJsb2ciOiJodHRwczovL2xvbmdmZWl6aGVuZy5naXRodWIuaW8vIiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6ImJmZmY0NjRjLTFiNTktNGZkNy1hNTE4LWU3YjY5MDFiNzU3YyIsImNsaWVudF9pZCI6Im1lcnJ5eW91In0.gp5t9nY9mGp5O2-yqdflc0nEAsTeCQG7VugA8q8XcF4
Header
Header 包含了一些元数据,至少会表明 token 类型以及 签名方法。
{
"typ": "JWT",
"alg": "HS256"
}
Claims (Payload)
Claims
部分包含了一些跟这个 token
有关的重要信息。
{
"user_name": "admin",
"scope": [
"all"
],
"exp": 1516726813,
"blog": "https://longfeizheng.github.io/",
"authorities": [
"ROLE_USER"
],
"jti": "bfff464c-1b59-4fd7-a518-e7b6901b757c",
"client_id": "merryyou"
}
Signature
JWT
标准遵照 JSON Web Signature (JWS)
标准来生成签名。签名主要用于验证 token
是否有效,是否被篡改。
JWT流程示意图
Spring Security Oauth2 实现JWT
配置TokenStoreConfig用于存储Token
@Configuration
public class TokenStoreConfig {
/**
* redis连接工厂
*/
@Autowired
private RedisConnectionFactory redisConnectionFactory;
/**
* 用于存放token
* @return
*/
@Bean
@ConditionalOnProperty(prefix = "merryyou.security.oauth2", name = "storeType", havingValue = "redis")
public TokenStore redisTokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
/**
* jwt TOKEN配置信息
*/
@Configuration
@ConditionalOnProperty(prefix = "merryyou.security.oauth2", name = "storeType", havingValue =