接着上一篇博客:https://www.cnblogs.com/wwjj4811/p/14505081.html

1|0JWT介绍

JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间作为JSON对象安全地传输信息。此信息可以通过数字签名进行验证和信任。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名,防止被篡改

1|1构成

JWT 有三部分构成:头部、有效载荷、签名

  • 头部:包含令牌的类型(JWT)与加密的签名算法(如 SHA256 或 ES256),Base64编码后加入第一部分

  • 有效载荷:通俗一点讲就是token中需要携带的信息都将存于此部分,比如:用户id、权限标识等信息。

    注:该部分信息任何人都可以读出来,所以添加的信息需要加密才会保证信息的安全性

  • 签名:用于防止 JWT 内容被篡改, 会将头部和有效载荷分别进行 Base64编码,编码后用.连接组成新的字符串,然后再使用头部声明的签名算法进行签名。在具有秘钥的情况下,可以验证JWT的准确性,是否被篡改

2|0认证服务器-对称加密 JWT 令牌

对称加密就是同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

2|1JWT 管理令牌

1.重构 com.wj.oauth2.server.config.TokenConfig 将令牌存储方式切换为 JWT


@Configuration public class TokenConfig { @Bean public TokenStore tokenStore(){ //jwt管理令牌 return new JwtTokenStore(jwtAccessTokenConverter()); } // JWT 签名秘钥 private static final String SIGNING_KEY = "wj-key"; @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setSigningKey(SIGNING_KEY); return jwtAccessTokenConverter; } }

2|2JWT转换器添加到令牌端点

修改AuthorizationServerConfig类:


@Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; /** * 重写父类的方法 */ @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { //密码模式需要设置此认证管理器 endpoints.authenticationManager(authenticationManager); // 刷新令牌获取新令牌时需要 endpoints.userDetailsService(customUserDetailsService); //设置token存储策略 endpoints.tokenStore(tokenStore).accessTokenConverter(jwtAccessTokenConverter); //授权码管理策略,针对授权码模式有效,会将授权码放到 auth_code 表,授权后就会删除它 endpoints.authorizationCodeServices(authorizationCodeServices()); }

2|3测试

使用密码授权模式获取access_token,发现access_token已经响应为jwt令牌

检查 JWT 令牌:http://localhost:8090/auth/oauth/check_token,已经包含了用户基本信息

3|0资源服务器-对称加密 JWT 令牌

在 JwtAccessTokenConverter 中使用了一个对称密钥来签署我们的令牌,意味着我们需要为资源服务器使用同样的密钥来验证签名合法性。

3|1JWT 管理令牌

这部分与认证服务器令牌配置是一样的, 将 JWT 令牌部分拷贝到cloud-oauth2-resource-product中的com.wj.oauth2.resource.config 包下即可.


@Configuration public class TokenConfig { @Bean public TokenStore tokenStore(){ //jwt管理令牌 return new JwtTokenStore(jwtAccessTokenConverter()); } // JWT 签名秘钥 private static final String SIGNING_KEY = "wj-key"; @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setSigningKey(SIGNING_KEY); return jwtAccessTokenConverter; } }

3|2资源服务器校验 JWT 令牌

修改ResourceServerConfig配置类:注释掉tokenService方法,并设置resources的tokenStore,就会自动本地校验jwt


@Configuration // 标识为资源服务器, 所有发往当前服务的请求,都会去请求头里找token,找不到或验证不通过不允许访问 @EnableResourceServer //开启方法级别权限控制 @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResourceServerConfig extends ResourceServerConfigurerAdapter { //配置当前资源服务器的ID private static final String RESOURCE_ID = "product-server"; @Autowired private TokenStore tokenStore; /**当前资源服务器的一些配置, 如资源服务器ID **/ @Override public void configure(ResourceServerSecurityConfigurer resources) { // 配置当前资源服务器的ID, 会在认证服务器验证(客户端表的resources配置了就可以访问这个服务) resources.resourceId(RESOURCE_ID) // 实现令牌服务, ResourceServerTokenServices实例 .tokenStore(tokenStore); } /* @Bean public ResourceServerTokenServices tokenService() { // 资源服务器去远程认证服务器验证 token 是否有效 RemoteTokenServices service = new RemoteTokenServices(); // 请求认证服务器验证URL,注意:默认这个端点是拒绝访问的,要设置认证后可访问 service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token"); // 在认证服务器配置的客户端id service.setClientId("wj-pc"); // 在认证服务器配置的客户端密码 service.setClientSecret("wj-secret"); return service; }*/ @Override public void configure(HttpSecurity http) throws Exception { http.sessionManagement() //不创建session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() //资源授权规则 .authorizeRequests() .antMatchers("/product/**").hasAuthority("product") //所有的请求对应访问的用户都要有all范围的权限 .antMatchers("/**").access("#oauth2.hasScope('all')"); } }

3|3测试

密码认证模式先获取access_token,再通过 JWT令牌查询获取商品资源

为了安全性, JWT令牌每次请求获取令牌都是响应一个新令牌,因为里面已经包含用户信息, 而之前的是令牌在有效时间里每次请求都是响应一样的令牌。

4|0认证服务器-非对称加密 JWT 令牌

非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用私钥对数据进行加密,只有用对应的公钥才能解密。

4|1生成密钥证书

公私密钥可以用jdk的命令keytool生成:别名为 oauth2,秘钥算法为 RSA,秘钥口令为 oauth2,秘钥库(文件)名称为 oauth2.jks,秘钥库(文件)口令为 oauth2


keytool -genkeypair -alias oauth2 -keyalg RSA -keypass oauth2 -keystore oauth2.jks -storepass oauth2

生成后,在命令执行命令的所在目录下会有一个oauth2.jks文件

将该文件移动到认证服务的resources目录下:

4|2非对称加密 JWT 令牌

修改认证服务的TokenConfig类:


@Configuration public class TokenConfig { @Bean public TokenStore tokenStore(){ //return new JdbcTokenStore(dataSource); //jwt管理令牌 return new JwtTokenStore(jwtAccessTokenConverter()); } @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); KeyStoreKeyFactory keyFactory = new KeyStoreKeyFactory(new ClassPathResource("oauth2.jks"), "oauth2".toCharArray()); jwtAccessTokenConverter.setKeyPair(keyFactory.getKeyPair("oauth2")); return jwtAccessTokenConverter; } }

4|3pom文件

修改认证服务的pom.xml


<build> <resources> <resource> <!-- 防止JKS被maven错误解析 --> <directory>src/main/resources</directory> <filtering>false</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.2.4.RELEASE</version> <configuration> <mainClass>com.wj.oauth2.AuthServerApplication</mainClass> </configuration> </plugin> </plugins> </build>

因为有可能jks文件无法正确被maven解析,导致项目启动报错。

5|0资源服务器-非对称加密 JWT 令牌

5|1根据密钥文件获取公钥

OpenSSL 是一个加解密工具包,可以使用 OpenSSL 来获取公钥,下载网址:http://slproweb.com/products/Win32OpenSSL.html

安装完成后,配置openssl环境变量,即安装目录\bin

5|2获取公钥

进入oauth2.jks所在目录执行命令:


keytool -list -rfc --keystore oauth2.jks | openssl x509 -inform pem -pubkey

复制出控制台打印出的内容到public.txt,并放到资源服务器的resources目录下(需要复制出public key的内容)

5|3非对称加密 JWT 令牌

修改资源服务器的TokenConfig类:


@Slf4j @Configuration public class TokenConfig { @Bean public TokenStore tokenStore(){ //jwt管理令牌 return new JwtTokenStore(jwtAccessTokenConverter()); } // JWT 签名秘钥 private static final String SIGNING_KEY = "wj-key"; @Bean public JwtAccessTokenConverter jwtAccessTokenConverter(){ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); ClassPathResource classPathResource = new ClassPathResource("public.txt"); String publicKey = null; try { publicKey=IOUtils.toString(classPathResource.getInputStream(),"UTF-8"); log.info("publicKey:{}" , publicKey); } catch (IOException e) { e.printStackTrace(); } jwtAccessTokenConverter.setVerifierKey(publicKey); return jwtAccessTokenConverter; } }

5|4测试

先请求access_token令牌:发现比对称加密的字符数目多了不少

发送请求,仍然可以请求成功

__EOF__

本文作者:秋风飒飒吹
本文链接:https://www.cnblogs.com/wwjj4811/p/14505886.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

Spring Security OAuth2:整合jwt相关推荐

  1. Spring Security OAuth2整合JWT

    文章目录 1. Spring Security 与 OAuth2 2. Spring Security OAuth2的配置和使用 ①:引入依赖 ②:配置 spring security ③:配置授权服 ...

  2. JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录

    文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...

  3. 基于 Spring Security OAuth2和 JWT 构建保护微服务系统

    我们希望自己的微服务能够在用户登录之后才可以访问,而单独给每个微服务单独做用户权限模块就显得很弱了,从复用角度来说是需要重构的,从功能角度来说,也是欠缺的.尤其是前后端完全分离之后,我们的用户信息不一 ...

  4. 《深入理解 Spring Cloud 与微服务构建》第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统

    <深入理解 Spring Cloud 与微服务构建>第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统 文章目录 <深入理解 Spring Cl ...

  5. 使用Spring Security Oauth2 和 JWT保护微服务--Uaa授权服务器的编写

    学习自深入理解微服务 采用Spring Security OAuth2 和 JWT的方式,Uaa服务只需要验证一次,返回JWT.返回的JWT包含了用户的所有信息,包括权限信息 从三个方面讲解: JWT ...

  6. 微信官方你真的懂OAuth2?Spring Security OAuth2整合企业微信扫码登录

    ❝ 企业微信扫码登录DEMO参见文末. 现在很多企业都接入了企业微信,作为私域社群工具,企业微信开放了很多API,可以打通很多自有的应用.既然是应用,那肯定需要做登录.正好企业微信提供了企业微信扫码授 ...

  7. 使用Spring Security Oauth2 和 JWT保护微服务--资源服务器的编写

    编写hcnet-website的资源服务 依赖管理pom文件 hcnet-website工程的pom文件继承主maven的pom文件.在hcnet-website工程的pom文件中添加web功能的起步 ...

  8. Spring Security Oauth2 解析jwt

  9. 使用Spring Security OAuth2使用JWT生成token及自定义token携带的信息(十)

    写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟.多谢!如果我的博客对你有帮助,欢迎进行评论✏️✏️.点赞

  10. Spring Security OAuth2 改变jwt带默认authorities信息

    上源码 Oauth2ServerConfig   add处新增 @Beanpublic JwtAccessTokenConverter accessTokenConverter() {JwtAcces ...

最新文章

  1. 报告:下一代技术革命“AI”来袭
  2. 如何解决make: Nothing to be done for `all‘ 的方法
  3. win10系统Mysql5.7服务启动报:1053错误:服务没有及时响应启动或控制请求
  4. App Store遭到攻击后如何保护iPhone安全
  5. pdfbox 按章节读取_2020年智慧树APP微生物与健康第五单元章节测试网课答案大学课后答案...
  6. 倪飞曝腾讯红魔6更多细节:搭载业内顶级散热技术
  7. [INS-32025] 所选安装与指定 Oracle 主目录中已安装的软件冲突。
  8. pytorch使用模型预测_使用PyTorch从零开始对边界框进行预测
  9. 家用台式计算机安装的软件,爱福窝家庭装修设计软件
  10. 人脸对齐--采用dlib库的68_face_landmark进行人脸对齐操作
  11. Android实现思维导图功能,Android实现思维导图
  12. iTunes历史各个版本下载地址
  13. 微信小程序开发中遇到的坑
  14. Vue 祖孙方法调用 祖父级方法在孙级调用 祖孙传参
  15. 阿里巴巴矢量图标库icon图标在线引用
  16. Java学习-发红包案例
  17. JAVA程序把大写转换小写_Java程序将字符串转换为小写和大写。
  18. 2.2 数据库应用系统开发方法
  19. 可能是历史上最伟大的一次 Git 代码提交
  20. 精美的HTML5焦点图特效

热门文章

  1. OrCAD Capture CIS 17.2导入Altium Designer原理图
  2. Spark的坑--Spark新手必看--Python Spark必读,耗费了我近三周的时间
  3. Andersen Global在南非拓展业务
  4. SSMS错误代码大全
  5. 5G系统新型网络架构
  6. 37、免驱动USB双目同步测距3D活体深度检测和RV1126结合V4L开发USB摄像头使用
  7. 《精要主义》读书笔记(一)
  8. ADC采集数据求平均
  9. 印度正试图建立世界上最大的面部识别系统
  10. SAP CDS UI 常用注解用法