SpringSecurityOAuth使用JWT Token
⒈JWT?
JWT(Json Web Token),是Json的一个开放的Token标准。
1,自包含,SpringSecurityOAuth的默认Token是UUID的一个随机的无意义的字符串,并不包含任何信息,信息是被单独存放的,我们还需要通过这个令牌从单独存放信息的存储那里获取信息,所以说SpringSecurityOAuth的默认Token比较依赖于存储,一旦存储信息的存储那里出现了故障,那么这个令牌就毫无用处了。而JWT Token中是包含有意义的信息的,当我们的系统拿到这个令牌以后,我们可以直接解析这个令牌来获取有用的信息。
2,密签,我们可以对发出去的令牌进行签名(指令牌被人篡改我们可以获知)
3,可扩展,Token中的信息我们可以根据业务需求进行扩展。
⒉如何在SpringSecurityOAuth中使用JWT Token替换掉默认的UUID Token
1.
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.security.oauth</groupId>
- <artifactId>spring-security-oauth2</artifactId>
- <version>2.3.5.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-test</artifactId>
- <scope>test</scope>
- </dependency>
2.
- package cn.coreqi.config;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Conditional;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
- import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
- @Configuration
- public class TokenStoreConfig {
- @Autowired
- private RedisConnectionFactory redisConnectionFactory;
- /**
- * TokenStore 负责令牌的存取
- * @return
- */
- // @Bean
- // public TokenStore redisTokenStore(){
- // return new RedisTokenStore(redisConnectionFactory);
- // }
- @Configuration
- public static class JwtTokenConfig {
- /**
- * Token生成中的处理
- * @return
- */
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter(){
- JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
- accessTokenConverter.setSigningKey("fanqi"); //Token签名用的密钥
- //发出去的令牌需要密钥签名,验令牌的时候也需要令牌来验签,如果他人获知了我们的密钥
- //就可以用我们的密钥来签发我们的JWT令牌,JWT唯一的安全性就是密钥
- //别人用我们的密钥来签发我们的JWT令牌就可以随意进入我们的系统
- return accessTokenConverter;
- }
- @Bean
- public TokenStore jwtTokenStore(){
- return new JwtTokenStore(jwtAccessTokenConverter());
- }
- }
- }
3.
- package cn.coreqi.config;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
- @Configuration
- @EnableAuthorizationServer //开启认证服务器
- public class CoreqiAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
- @Autowired
- //@Qualifier("authenticationManagerBean")
- private AuthenticationManager authenticationManager;
- @Autowired
- private UserDetailsService userDetailsService;
- @Autowired
- private TokenStore jwtTokenStore;
- @Autowired(required = false)
- private JwtAccessTokenConverter jwtAccessTokenConverter;
- // @Autowired
- // private AuthenticationConfiguration authenticationConfiguration;
- /**
- * 针对端点的配置
- * @param authorizationServerEndpointsConfigurer
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer authorizationServerEndpointsConfigurer) throws Exception {
- //authorizationServerEndpointsConfigurer.authenticationManager(authenticationConfiguration.getAuthenticationManager());
- authorizationServerEndpointsConfigurer.tokenStore(jwtTokenStore) //使用JwtToken
- .authenticationManager(authenticationManager)
- .userDetailsService(userDetailsService);
- if(jwtAccessTokenConverter != null){
- authorizationServerEndpointsConfigurer.accessTokenConverter(jwtAccessTokenConverter);
- }
- }
- /**
- * 第三方应用客户端的有关配置
- * @param clientDetailsServiceConfigurer
- * @throws Exception
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
- clientDetailsServiceConfigurer.inMemory()
- .withClient("coreqi") //client_id
- .secret("coreqiSecret") //client_id的密码
- .accessTokenValiditySeconds(7200) //令牌的有效时间(单位秒)
- .redirectUris("https://www.baidu.com")
- .scopes("all","read","write") //所支持的权限有那些
- .authorities("COREQI_READ")
- .authorizedGrantTypes("authorization_code","password"); //针对当前client所支持的授权模式
- }
- /**
- * 针对安全性有关的配置
- * @param security
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- super.configure(security);
- }
- }
⒊如何扩展Jwt Token中的信息
- package cn.coreqi.jwt;
- import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
- import org.springframework.security.oauth2.common.OAuth2AccessToken;
- import org.springframework.security.oauth2.provider.OAuth2Authentication;
- import org.springframework.security.oauth2.provider.token.TokenEnhancer;
- import java.util.HashMap;
- import java.util.Map;
- public class CoreqiJwtTokenEnhancer implements TokenEnhancer {
- @Override
- public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
- Map<String,Object> info = new HashMap<>(); //要往accessToken中存放的信息
- info.put("company","fanqi");
- ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(info); //设置附加信息
- return accessToken;
- }
- }
- package cn.coreqi.config;
- import cn.coreqi.jwt.CoreqiJwtTokenEnhancer;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Conditional;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.security.oauth2.provider.token.TokenEnhancer;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
- import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
- @Configuration
- public class TokenStoreConfig {
- @Autowired
- private RedisConnectionFactory redisConnectionFactory;
- /**
- * TokenStore 负责令牌的存取
- * @return
- */
- // @Bean
- // public TokenStore redisTokenStore(){
- // return new RedisTokenStore(redisConnectionFactory);
- // }
- @Configuration
- public static class JwtTokenConfig {
- /**
- * Token生成中的处理
- * @return
- */
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter(){
- JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
- accessTokenConverter.setSigningKey("fanqi"); //Token签名用的密钥
- //发出去的令牌需要密钥签名,验令牌的时候也需要令牌来验签,如果他人获知了我们的密钥
- //就可以用我们的密钥来签发我们的JWT令牌,JWT唯一的安全性就是密钥
- //别人用我们的密钥来签发我们的JWT令牌就可以随意进入我们的系统
- return accessTokenConverter;
- }
- @Bean
- public TokenStore jwtTokenStore(){
- return new JwtTokenStore(jwtAccessTokenConverter());
- }
- @Bean
- public TokenEnhancer jwtTokenEnhancer(){
- return new CoreqiJwtTokenEnhancer();
- }
- }
- }
- package cn.coreqi.config;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
- import org.springframework.security.oauth2.provider.token.TokenEnhancer;
- import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
- import java.util.ArrayList;
- import java.util.List;
- @Configuration
- @EnableAuthorizationServer //开启认证服务器
- public class CoreqiAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
- @Autowired
- //@Qualifier("authenticationManagerBean")
- private AuthenticationManager authenticationManager;
- @Autowired
- private UserDetailsService userDetailsService;
- @Autowired
- private TokenStore jwtTokenStore;
- @Autowired(required = false)
- private JwtAccessTokenConverter jwtAccessTokenConverter;
- @Autowired(required = false)
- private TokenEnhancer jwtTokenEnhancer;
- // @Autowired
- // private AuthenticationConfiguration authenticationConfiguration;
- /**
- * 针对端点的配置
- * @param authorizationServerEndpointsConfigurer
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer authorizationServerEndpointsConfigurer) throws Exception {
- //authorizationServerEndpointsConfigurer.authenticationManager(authenticationConfiguration.getAuthenticationManager());
- authorizationServerEndpointsConfigurer.tokenStore(jwtTokenStore) //使用JwtToken
- .authenticationManager(authenticationManager)
- .userDetailsService(userDetailsService);
- if(jwtAccessTokenConverter != null && jwtTokenEnhancer != null){
- TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); //Token增强器
- List<TokenEnhancer> enhancers = new ArrayList<>();
- enhancers.add(jwtTokenEnhancer);
- enhancers.add(jwtAccessTokenConverter);
- enhancerChain.setTokenEnhancers(enhancers);
- authorizationServerEndpointsConfigurer.tokenEnhancer(enhancerChain)
- .accessTokenConverter(jwtAccessTokenConverter);
- }
- }
- /**
- * 第三方应用客户端的有关配置
- * @param clientDetailsServiceConfigurer
- * @throws Exception
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
- clientDetailsServiceConfigurer.inMemory()
- .withClient("coreqi") //client_id
- .secret("coreqiSecret") //client_id的密码
- .accessTokenValiditySeconds(7200) //令牌的有效时间(单位秒)
- .redirectUris("https://www.baidu.com")
- .scopes("all","read","write") //所支持的权限有那些
- .authorities("COREQI_READ")
- .authorizedGrantTypes("authorization_code","password"); //针对当前client所支持的授权模式
- }
- /**
- * 针对安全性有关的配置
- * @param security
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- super.configure(security);
- }
- }
⒋控制器如何识别Token中扩展的信息
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.9.1</version>
- </dependency>
- package cn.coreqi.controller;
- import io.jsonwebtoken.Claims;
- import io.jsonwebtoken.Jwts;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- import javax.servlet.http.HttpServletRequest;
- import java.io.UnsupportedEncodingException;
- import java.net.Authenticator;
- @RestController
- public class UserController {
- @GetMapping("/user/me")
- public Object getCurrentUser(Authenticator user , HttpServletRequest request) throws UnsupportedEncodingException {
- String header = request.getHeader("Authorization");
- String token = StringUtils.substringAfter(header,"bearer ");
- Claims claims = Jwts.parser().setSigningKey("fanqi".getBytes("UTF-8")).parseClaimsJws(token).getBody();
- String company = (String) claims.get("company");
- System.out.println(company);
- return user;
- }
- }
SpringSecurityOAuth使用JWT Token的更多相关文章
- SpringSecurityOAuth使用JWT Token实现SSO单点登录
⒈认证服务器 1.添加pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti ...
- Spring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证
关于 Jwt Token 的签名与安全性前面已经做了几篇介绍,在 IdentityServer4 中定义了 Jwt Token 与 Reference Token 两种验证方式(https://www ...
- ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露
一.前言 在涉及到后端项目的开发中,如何实现对于用户权限的管控是需要我们首先考虑的,在实际开发过程中,我们可能会运用一些已经成熟的解决方案帮助我们实现这一功能,而在 Grapefruit.VuCore ...
- 关于 IdentityServer4 中的 Jwt Token 与 Reference Token
OpenID Connect(Core),OAuth 2.0(RFC 6749),JSON Web Token (JWT)(RFC 7519) 之间有着密不可分联系,对比了不同语言的实现,还是觉得 I ...
- 如何在启用JWT Token授权的.NET Core WebApi项目中下载文件
背景 前几天,做项目的时候遇到一个文件下载的问题.当前系统是一个前后端分离的项目,前端是一个AngularJs项目, 后端是一个.NET Core WebApi项目.后端的Api项目使用了Jwt To ...
- 【ASP.NET Core快速入门】(十一)应用Jwtbearer Authentication、生成jwt token
准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...
- Django JWT Token RestfulAPI用户认证
一般情况下我们Django默认的用户系统是满足不了我们的需求的,那么我们会对他做一定的扩展 创建用户项目 python manage.py startapp users 添加项目apps INSTAL ...
- 咏南中间件支持JWT TOKEN
咏南中间件支持JWT TOKEN
- 菜鸟入门【ASP.NET Core】11:应用Jwtbearer Authentication、生成jwt token
准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...
随机推荐
- webpack打包进内联html
用到一个新插件:html-webpack-inline-source-plugin(依赖于html-webpack-plugin) 1.安装 npm i -D html-webpack-inline- ...
- Spring_xml和注解混合方式开发
1. spring核心配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...
- ElasticSearch的插件(Plugins)介绍
ElasticSearch的插件(Plugins)介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 目前可以扩展ElasticSearch功能的插件有很多,比如:添加自定义的映 ...
- java中用jdom创建xml文档/将数据写入XML中
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; i ...
- HDU 1027(数字排列 STL)
题意是求 n 个数在全排列中的第 m 个序列. 直接用 stl 中的 next_permutation(a, a+n) (这个函数是求一段序列的下一个序列的) 代码如下: #include <b ...
- Python复习笔记(五)面向对象
1. __init__方法 # 1. 为对象在内存 中分配空间 -- 创建对象 # 2. 为对象属性 设置初始值 -- 初始化方法(init)+-------------- # 3. __init__ ...
- freemarker迭代list、map等常规操作,将数据放到模板中
转自:https://blog.csdn.net/wickedvalley/article/details/65937189 一.controller开始准备模型.数据1.po类 package co ...
- IDEA导入JUnit4
Step 1. IDEA最上面一栏的菜单栏中,选File->Project Structure(从上往下第11个),弹出窗口左边有一个列表,选Module. Step 2. 右侧有一个带3个标签 ...
- 使用 Quartz.NET 实现作业串行执行
Ø 前言 前两天,在公司的一个项目中编写 Windows 服务时,需求是当A服务运行完后,B服务才能运行,B服务运行后,C服务才能运行.因为B服务的数据依赖于A服务生成的数据,而C服务的数据又依赖于 ...
- JS创建对象之构造函数模式
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = f ...