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 ...
随机推荐
- Centos7安装Mysql5.7方法总结 - 实操手册
Centos7.x版本下针对Mysql的安装和使用多少跟之前的Centos6之前版本有所不同的,废话就不多赘述了,下面介绍下在centos7.x环境里安装mysql5.7的几种方法:一.yum方式安装 ...
- Java面向对象类与对象整理
第一章 面向对象: 1.1 什么是面向过程: 遇到某件事的时候,思考 “我该怎么做”然后一步一步实现的过程 1.2 什么是面向对象: 遇到某件事的时 ...
- maven_eclipse配置maven
1.eclipse配置3.3.9版本的maven 2.修改仓库位置
- Python的基础详情
Python的基础信息 Python是一种动态解释性高级语言 Python即可面向对象,也可以面向过程 解释行语言 无需编译 程序以'行'为单位进行执行 执行速度慢 开发效率快 可跨平台 编译型语言 ...
- /etc/fstab 文件挂载配置文件
(1)/etc/fstab 每行定义一个要挂载的文件系统 mount -a 自动挂载/etc/fstab文件没有挂载的设备,不管已挂载过的设备 如果想刷新修改过已挂载的设备,mount -o remo ...
- @jsonProperty 实现返回自定义属性名字
实现场景: 比如说前端需要返回userPic 这个字段,但是我们数据库定义的是pic字段. 可以用@jsonProperty 来实现 public class User{ @JsonProperty( ...
- Ubuntu Server 16.04 安装MySQL并设置远程访问
Ubuntu Server 16.04 安装MySQL 1. 使用root账号 sudo apt-get install mysql-serversudo apt-get install mysql- ...
- 067、如何部署Calico网络 (2019-04-10 周三)
参考https://www.cnblogs.com/CloudMan6/p/7509975.html Calico 是一个纯三层的虚拟网络方案,Calico为每个容器分配一个IP,每个host都是 ...
- 804. Unique Morse Code Words
Description International Morse Code defines a standard encoding where each letter is mapped to a se ...
- java的几个奇怪语法
=============================Java 双冒号 :: 语法的含义=============================下面的代码中有双冒号,初看上去很奇怪, list. ...