文章目录
- 1. JWT令牌介绍
- 1.1 什么是JWT?
- 1.2 JWT的结构
- 1.3 JWT的应用场景
- 2 如何配置JWT令牌
- 2.1 修改UAA工程配置JWT令牌服务
- 2.2 修改业务模块的代码本地检查令牌
1. JWT令牌介绍
1.1 什么是JWT?
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为JSON对象。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),通过点号(.)分隔。
JWT的主要特点:
- 紧凑性:体积小,可通过URL、POST参数或HTTP头部传输
- 自包含性:包含所有必要信息,减少数据库查询
- 安全性:使用签名确保令牌不被篡改
- 标准化:基于JSON格式,跨语言支持良好
1.2 JWT的结构
一个典型的JWT令牌格式:xxxxx.yyyyy.zzzzz
1. 头部(Header)
{"alg":"HS256","typ":"JWT"}alg:签名算法(如HS256、RS256)typ:令牌类型,固定为"JWT"
2. 载荷(Payload)
包含声明(claims),分为三类:
- 注册声明:预定义的声明,如iss(签发者)、exp(过期时间)、sub(主题)
- 公共声明:可自定义,但应避免冲突
- 私有声明:自定义声明,用于传递业务数据
3. 签名(Signature)
使用头部指定的算法,对编码后的头部和载荷进行签名,确保令牌完整性。
1.3 JWT的应用场景
- 身份认证:用户登录后,服务器生成JWT返回给客户端
- 授权:访问受保护资源时,客户端携带JWT
- 信息交换:安全地在各方之间传递信息
2 如何配置JWT令牌
2.1 修改UAA工程配置JWT令牌服务
(1)配置JWT令牌存储和密钥(这里配置加密和解密相同密码)
publicclassTokenConfig{privateStringSIGNING_KEY="123456";// @Bean// public TokenStore tokenStore(){// /**// * 使用内存存储令牌(普通令牌)// */// return new InMemoryTokenStore();// }/** * 配置JWT令牌存储 * @return */@BeanpublicTokenStoretokenStore(){returnnewJwtTokenStore(accessTokenConverter());}@BeanpublicJwtAccessTokenConverteraccessTokenConverter(){JwtAccessTokenConverterconverter=newJwtAccessTokenConverter();converter.setSigningKey(SIGNING_KEY);returnconverter;}}(2) 配置AuthorizationServer 令牌增强
...............@AutowiredprivateClientDetailsServiceclientDetailsService;................//令牌增强TokenEnhancerChaintokenEnhancerChain=newTokenEnhancerChain();tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));service.setTokenEnhancer(tokenEnhancerChain);(3)获取令牌(测试)。启动UAA后,获取令牌,可以看到令牌的长度比较厂,格式如何JWT令牌格式。
(4) 校验令牌(测试)。拿到前面的令牌,使用/uaa/oauth/check_token 接口查看令牌内容。
2.2 修改业务模块的代码本地检查令牌
(1)在order工程中,配置config下创建TokenConfig,代码与UAA下面的TokenConfig一致
packagecom.it2.security.distributed.order.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.oauth2.provider.token.TokenStore;importorg.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;importorg.springframework.security.oauth2.provider.token.store.JwtTokenStore;@ConfigurationpublicclassTokenConfig{privateStringSIGNING_KEY="123456";// @Bean// public TokenStore tokenStore(){// /**// * 使用内存存储令牌(普通令牌)// */// return new InMemoryTokenStore();// }/** * 配置JWT令牌存储 * @return */@BeanpublicTokenStoretokenStore(){returnnewJwtTokenStore(accessTokenConverter());}@BeanpublicJwtAccessTokenConverteraccessTokenConverter(){JwtAccessTokenConverterconverter=newJwtAccessTokenConverter();converter.setSigningKey(SIGNING_KEY);returnconverter;}}(2) 将TokenStore 注入到资源服务中使用,并注释之前的远程令牌验证
@AutowiredprivateTokenStoretokenStore;@Overridepublicvoidconfigure(ResourceServerSecurityConfigurerresources)throwsException{resources.resourceId(RESOURCE_ID)//资源id.tokenStore(tokenStore)//自己验证令牌// .tokenServices(tokenService()) //验证令牌的服务.stateless(true);}(3)启动order服务,并关闭UAA,使用刚刚获取的JWT令牌访问r1资源.,可以正常访问,说明了业务服务没有使用远程认证的方式校验令牌,而是自己本地校验令牌。