使用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 ...
随机推荐
- 【UOJ#242】【UR#16】破坏蛋糕(计算几何)
[UOJ#242][UR#16]破坏蛋糕(计算几何) 题面 UOJ 题解 为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(y\)轴. 于是我们可以处理出所有交点,然后把它们 ...
- 【转载】Gradle for Android 第四篇( 构建变体 )
当你在开发一个app,通常你会有几个版本.大多数情况是你需要一个开发版本,用来测试app和弄清它的质量,然后还需要一个生产版本.这些版本通常有不同的设置,例如不同的URL地址.更可能的是你可能需要一个 ...
- 工具类Base64Util
在和服务器交互的过程中,有时候我们需要把图片编码成base64字符串传输,记录一下工具类 import android.graphics.Bitmap; import android.graphics ...
- Xamarin学习(一)---- 环境准备
前言: 摸索学习Xamarin的应用,以此博客跟进学习进度. 介绍: Xamarin 提供了用于移动设备.平板电脑和桌面应用程序的跨平台开发解决方案.Xamarin 产品依赖于 Apple 和 ...
- FastJSON使用例子
FastjsonTest.java package demo; import java.util.ArrayList; import java.util.Date; import java.util. ...
- Vue实战狗尾草博客管理平台第六章
Vue实现狗尾草博客后台管理系统第六章 本章节内容 文章列表 文章详情 草稿箱 文章发布. 本章节内容呢,开发的很是随意哈,因为多数就是element-ui的使用,熟悉的童鞋,是可以很快完成本章节的内 ...
- SRDC - ORA-1555 during Export: Checklist of Evidence to Supply (Doc ID 1682706.1)
SRDC - ORA-1555 during Export: Checklist of Evidence to Supply (Doc ID 1682706.1) Action Plan 1. Exe ...
- Python的 json 、 hashlib 、 Base64 模块
json模块 简介 全称"JavaScript Object Notation" (JavaScript对象表示法)它是一种基于文本,独立于语言的轻量级数据交换格式 以易于让人阅读 ...
- prometheus operator的深度好文
转: https://www.servicemesher.com/blog/prometheus-operator-manual/
- 【BZOJ2138】stone(线段树+hall定理)
传送门 题意: 现在有\(n\)堆石子,每堆石子有\(a_i\)个. 之后会有\(m\)次,每次选择\([l,r]\)的石子堆中的石子扔\(k\)个,若不足,则尽量扔. 现在输出\(1\)~\(m\) ...