使用Redis作为Spring Security OAuth2的token存储
写在前边
本文对Spring Security OAuth2的token使用Redis保存,相比JWT实现的token存储,Redis可以随时吊销access_token,并且Redis响应速度很快,没有加密解密的过程
本文源代码在redis-token-saved模块中,仓库地址:https://github.com/hellxz/spring-security-oauth2-learn
这里就不做测试了,仅做简记
代码层级

Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Security OAuth2 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
授权服务器保存token到Redis
application.yml
server:
port: 8080
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123
database: 0
AuthorizationConfig
@Configuration
@EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
/**
* redis工厂,默认使用lettue
*/
@Autowired
public RedisConnectionFactory redisConnectionFactory;
/**
* 用户认证管理器
*/
@Autowired
public AuthenticationManager authenticationManager;
/**
* 用户服务
*/
@Autowired
public UserDetailsService userDetailsService;
/**
* 密码加密器
*/
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 授权服务安全配置,主要用于放行客户端访问授权服务接口
*
* @param security AuthorizationServerSecurityConfigurer
* @throws Exception 异常
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
//允许客户端表单提交
security.allowFormAuthenticationForClients()
//客户端校验token访问许可
.checkTokenAccess("permitAll()")
//客户端token调用许可
.tokenKeyAccess("permitAll()");
}
/**
* 客户端信息配置,可配置多个客户端,这里可以使用配置文件进行代替
*
* @param clients 客户端设置
* @throws Exception 异常
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client-a")
.secret(passwordEncoder.encode("client-a-secret"))
.redirectUris("http://localhost:9001/callback")
//支持 授权码、密码两种授权模式,支持刷新token功能
.authorizedGrantTypes("authorization_code", "password", "refresh_token");
}
/**
* 配置端点
*
* @param endpoints 端点
* @throws Exception 异常
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//配置认证管理器
endpoints.authenticationManager(authenticationManager)
//配置用户服务
.userDetailsService(userDetailsService)
//配置token存储的服务与位置
.tokenServices(tokenService())
.tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore() {
//使用redis存储token
RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
//设置redis token存储中的前缀
redisTokenStore.setPrefix("auth-token:");
return redisTokenStore;
}
@Bean
public DefaultTokenServices tokenService() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
//配置token存储
tokenServices.setTokenStore(tokenStore());
//开启支持refresh_token,此处如果之前没有配置,启动服务后再配置重启服务,可能会导致不返回token的问题,解决方式:清除redis对应token存储
tokenServices.setSupportRefreshToken(true);
//复用refresh_token
tokenServices.setReuseRefreshToken(true);
//token有效期,设置12小时
tokenServices.setAccessTokenValiditySeconds(12 * 60 * 60);
//refresh_token有效期,设置一周
tokenServices.setRefreshTokenValiditySeconds(7 * 24 * 60 * 60);
return tokenServices;
}
}
SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 配置认证管理器信息,这里可以使用UserDetailsService实现类来提供用户信息,或Provider+UserDetailsService
*
* @param auth 认证管理器配置
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//@formatter:off
auth.inMemoryAuthentication()
.withUser("hellxz")
.password(passwordEncoder().encode("test"))
.authorities(AuthorityUtils.createAuthorityList("all"));
//@formatter:on
}
/**
* 配置http访问控制
*
* @param http http安全配置
* @throws Exception 异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//放行options方法请求
.antMatchers(HttpMethod.OPTIONS).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
启动类
/**
* redis作为token存储的授权server
*/
@SpringBootApplication
public class RedisAuthorizationServer {
public static void main(String[] args) {
SpringApplication.run(RedisAuthorizationServer.class, args);
}
}
资源服务器访问Redis校验token配置
application.yml
server:
port: 8081
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123
database: 0
ResourceServerConfig
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
//无状态
resources.stateless(true);
//设置token存储
resources.tokenStore(tokenStore());
}
/**
* 设置token存储,这一点配置要与授权服务器相一致
*/
@Bean
public RedisTokenStore tokenStore(){
RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
redisTokenStore.setPrefix("auth-token:");
return redisTokenStore;
}
}
SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
ResourceController
@RestController
public class ResourceController {
private static final Logger log = LoggerFactory.getLogger(ResourceController.class);
@GetMapping("/user/{username}")
public UserVO user(@PathVariable String username){
log.info("{}", SecurityContextHolder.getContext().getAuthentication());
return new UserVO(username, username + "@foxmail.com");
}
}
UserVO
package com.github.hellxz.oauth2.web.vo;
public class UserVO {
private String username;
private String email;
public UserVO(String username, String email) {
this.username = username;
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
启动类
/**
* 使用redis作为token存储的资源服务器,这里不使用调用授权服务器的方式去校验资源,只需要从redis中取token进行判断即可
*/
@SpringBootApplication
public class RedisResourceServer {
public static void main(String[] args) {
SpringApplication.run(RedisResourceServer.class, args);
}
}
使用Redis作为Spring Security OAuth2的token存储的更多相关文章
- 使用JWT作为Spring Security OAuth2的token存储
序 Spring Security OAuth2的demo在前几篇文章中已经讲过了,在那些模式中使用的都是RemoteTokenService调用授权服务器来校验token,返回校验通过的用户信息供上 ...
- Spring Security Oauth2 使用 token 访问资源服务器出现异常:Invalid token does not contain resource id (oauth2)
异常如图 查看资源服务器的日志 p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error=&quo ...
- Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战
一. 前言 [APP 移动端]Spring Security OAuth2 手机短信验证码模式 [微信小程序]Spring Security OAuth2 微信授权模式 [管理系统]Spring Se ...
- spring security oauth2 搭建认证中心demo
oauth2 介绍 oauth2 协议应该是开发者们耳熟能详的协议了,这里就不做过多的介绍了,具体介绍如何在spring security中搭建oauth2的认证服务.Spring-Securit ...
- spring security oauth2 client_credentials模
spring security oauth2 client_credentials模 https://www.jianshu.com/p/1c3eea71410e 序 本文主要简单介绍一下spring ...
- Spring security + oauth2.0 + redis + mybatis plus 搭建微服务
上个星期一个朋友请求帮忙,让我搭建一个分布式授权中心的微服务,之前我也没搭建过,在网上撸了几天前辈们写的技术博客,搞出个模型,分享给大家: 前辈们博客地址: OAuth2.0 原理:https://b ...
- spring security oauth2搭建resource-server demo及token改造成JWT令牌
我们在上文讲了如何在spring security的环境中搭建基于oauth2协议的认证中心demo:https://www.cnblogs.com/process-h/p/15688971.html ...
- 关于 Spring Security OAuth2 中 Feign 调用 Token 问题
微服务体系中,避免不了服务之间链式调用,一般使用 Feign ,由于使用 Spring Security OAuth2 全局做了安全认证,简单的一种实现方式就是在服务提供方获得 Token 再次通过 ...
- Spring Security Oauth2 的配置
使用oauth2保护你的应用,可以分为简易的分为三个步骤 配置资源服务器 配置认证服务器 配置spring security 前两点是oauth2的主体内容,但前面我已经描述过了,spring sec ...
随机推荐
- CSP-S 爆零记
抱歉,这么晚才更. 事实是:我都没有去 所以爆零了 QwQ
- 数据库——SQL-SERVER练习(3)数据更新 视图
(1). 将一个新学生记录(学号:95020:姓名:陈冬:性别:男:所在系:IS:年龄:18岁)插入到Student表中.(注意, 学号是主码不允许重复,一个学号只能插入一次,学号是5位数,不要用书 ...
- django7-cookie与session
1.有状态服务与无状态服务 服务实例存储了客户端的数据 ,那么这就是个有状态服务 服务实例不存储客户端数据 ,让其他缓存存储客户端数据 ,这就是无状态服务 ,http就是无状态的 2.什么是cooki ...
- Spring高频面试题,你能答的上哪些?(高级篇)
1.什么是 Spring 框架?Spring 框架有哪些主要模块? 2.使用 Spring 框架能带来哪些好处? 3.什么是控制反转(IOC)?什么是依赖注入? 4.请解释下 Spring 框架中的 ...
- 爬取动态html网页,requests+execjs
请求地址:https://g.hongshu.com/content/99269/15382723.html 网页内容为动态执行js所得 1.直接浏览器模拟 不用考虑页面的业务逻辑什么的,直接得到结果 ...
- v8js-在PHP中运行javascript代码
起因之前写自动登录操作一个网站的PHP脚本,但是发现该网站用js代码做了cookie的计算和验证,所以使用了v8js. 安装安装v8.(Mac:brew install v8)使用pecl insta ...
- Java collection 集合类架构
https://www.cnblogs.com/fireflyupup/p/4875130.html Collection List 在Collection的基础上引入了有序的概念,位置精确:允许相同 ...
- [20190823]关于CPU成本计算3.txt
[20190823]关于CPU成本计算3.txt --//前几天探究CPU cost时遇到的问题,获取行成本时我的测试查询结果出现跳跃,不知道为什么,感觉有点奇怪,分析看看.--//ITPUB原始链接 ...
- bayaim_hadoop1_2.2.0伪分布式搭建
------------------bayaim_hadoop1_2.2.0伪分布式搭建_2018年11月06日09:21:46--------------------------------- 1. ...
- mySql创建带解释的表及给表和字段加注释的实现代码
1.创建带解释的表 CREATE TABLE test_table( t_id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '设置主键自增', t_name ...