Spring Cloud Security OAuth2 JWT令牌
文章目录
一、JWT令牌简介
1.1前言
当资源服务和授权服务不在一起时资源服务使用RemoteTokenServices
远程请求授权服务验证token,如果访问量较大将会影响系统的性能 。
令牌采用JWT
格式即可解决上边的问题,用户认证通过会得到一个JWT
令牌,JWT
令牌中已经包括了用户相关的信息,客户端只需要携带JWT
访问资源服务,资源服务根据事先约定的算法自行完成令牌校验,无需每次都请求认证 服务完成授权。
JWT:JSON Web Token
(JWT
)是一个开放的行业标准(RFC 7519
),它定义了一种简介的、自包含的协议格式,用于 在通信双方传递json
对象,传递的信息经过数字签名可以被验证和信任。JWT
可以使用HMAC
算法或使用RSA
的公钥/私钥对来签名,防止被篡改。
1.2 JWT的优缺点
JWT令牌的优点
- jwt基于json,非常方便解析
- 可以在令牌中自定义丰富的内容,易扩展
- 通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高
- 资源服务使用JWT可不依赖认证服务即可完成授权
JWT令牌的缺点
- JWT令牌较长,占存储空间比较大
1.3 JWT令牌结构
JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz
①Header
头部包括令牌的类型(即JWT
)及使用的哈希算法(如HMAC
、SHA256
或RSA
),例:
{
"alg": "HS256",
"typ": "JWT"
}
将上边的内容使用Base64Url编码,得到一个字符串就是JWT令牌的第一部分。
②Payload
第二部分是负载,内容也是一个json
对象,它是存放有效信息的地方,它可以存放jwt
提供的现成字段,比如:iss
(签发者),exp
(过期时间戳), sub
(面向的用户)等,也可自定义字段。 此部分不建议存放敏感信息,因为此部分可以解码还原原始内容。 最后将第二部分负载使用Base64Url
编码,得到一个字符串就是JWT
令牌的第二部分。
{
"sub": "123",
"name": "Wang",
"admin": true
}
③Signature
第三部分是签名,此部分用于防止jwt
内容被篡改。 这个部分使用Base64url
将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header
中声明 签名算法进行签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
二、配置JWT令牌服务
代码和环境搭建忽略,详情见:https://github.com/hucheng1997/security-oauth2
2.1 配置tokenStore
@Configuration
public class TokenConfig {
private static final String SIGN_KEY = "hello123";
@Bean
public JwtAccessTokenConverter tokenConverter() {
JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
//采用对称加密算法
tokenConverter.setSigningKey(SIGN_KEY);
return tokenConverter;
}
@Bean
public TokenStore tokenStore() {
//将用户信息存储在token中,性能更快
return new JwtTokenStore(tokenConverter());
}
}
2.2 使用JWT Token
2.3 测试
三、配置JWT资源服务
复制TokenConfig
到资源服务,然后配置:
测试:
四、数据库配置ClientDetail和授权码
生产环境中客户端信息和授权码会存储在数据库中,下边完善环境的配置
①新建数据库表
--客户端信息表
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`resource_ids` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_secret` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scope` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorized_grant_types` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`web_server_redirect_uri` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorities` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`access_token_validity` int(11) NULL DEFAULT NULL,
`refresh_token_validity` int(11) NULL DEFAULT NULL,
`additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`autoapprove` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `oauth_client_details` VALUES ('c1', 'res1', '$2a$10$w1Zgh5Xu52J2oT3LMDOf4OkTY3IC3v3PI1ICWSMXPmw.XT27aqW12', 'all', 'authorization_code,password,client_credentials,implicit,refresh_token', 'http://www.baidu.com', NULL, 300, 1500, NULL, 'false');
INSERT INTO `oauth_client_details` VALUES ('c2', 'res2', '$2a$10$w1Zgh5Xu52J2oT3LMDOf4OkTY3IC3v3PI1ICWSMXPmw.XT27aqW12', 'all', 'authorization_code,password,client_credentials,implicit,refresh_token', 'http://www.baidu.com', NULL, 300, 1500, NULL, 'false');
--存储授权码表
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code` ( `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `authentication` blob NULL,
INDEX `code_index`(`code`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
②修改代码
③测试
推荐阅读
-
SpringBoot+Spring Security+JWT实现RESTful Api权限控制的方法
-
Spring Boot Security 结合 JWT 实现无状态的分布式API接口
-
Spring Security OAuth2集成短信验证码登录以及第三方登录
-
Spring Security结合JWT的方法教程
-
Spring Security OAuth2集成短信验证码登录以及第三方登录
-
Spring Boot Security OAuth2 实现支持JWT令牌的授权服务器
-
微信授权就是这个原理,Spring Cloud OAuth2 授权码模式
-
Spring Cloud系列-Zuul网关集成JWT身份验证
-
使用Spring Security OAuth2实现单点登录
-
Spring Security 解析(七) —— Spring Security Oauth2 源码解析