写在前边

本文对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存储的更多相关文章

  1. 使用JWT作为Spring Security OAuth2的token存储

    序 Spring Security OAuth2的demo在前几篇文章中已经讲过了,在那些模式中使用的都是RemoteTokenService调用授权服务器来校验token,返回校验通过的用户信息供上 ...

  2. Spring Security Oauth2 使用 token 访问资源服务器出现异常:Invalid token does not contain resource id (oauth2)

    异常如图 查看资源服务器的日志 p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error=&quo ...

  3. Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战

    一. 前言 [APP 移动端]Spring Security OAuth2 手机短信验证码模式 [微信小程序]Spring Security OAuth2 微信授权模式 [管理系统]Spring Se ...

  4. spring security oauth2 搭建认证中心demo

    oauth2 介绍 ​ oauth2 协议应该是开发者们耳熟能详的协议了,这里就不做过多的介绍了,具体介绍如何在spring security中搭建oauth2的认证服务.Spring-Securit ...

  5. spring security oauth2 client_credentials模

    spring security oauth2 client_credentials模 https://www.jianshu.com/p/1c3eea71410e 序 本文主要简单介绍一下spring ...

  6. Spring security + oauth2.0 + redis + mybatis plus 搭建微服务

    上个星期一个朋友请求帮忙,让我搭建一个分布式授权中心的微服务,之前我也没搭建过,在网上撸了几天前辈们写的技术博客,搞出个模型,分享给大家: 前辈们博客地址: OAuth2.0 原理:https://b ...

  7. spring security oauth2搭建resource-server demo及token改造成JWT令牌

    我们在上文讲了如何在spring security的环境中搭建基于oauth2协议的认证中心demo:https://www.cnblogs.com/process-h/p/15688971.html ...

  8. 关于 Spring Security OAuth2 中 Feign 调用 Token 问题

    微服务体系中,避免不了服务之间链式调用,一般使用 Feign ,由于使用 Spring Security OAuth2 全局做了安全认证,简单的一种实现方式就是在服务提供方获得 Token 再次通过 ...

  9. Spring Security Oauth2 的配置

    使用oauth2保护你的应用,可以分为简易的分为三个步骤 配置资源服务器 配置认证服务器 配置spring security 前两点是oauth2的主体内容,但前面我已经描述过了,spring sec ...

随机推荐

  1. 基于 EntityFramework 生成 Repository 模式代码

    借助 WeihanLi.EntityFramework 实现简单的 Repository Intro 很多时候一些简单的业务都是简单的增删改查,动态生成一些代码完成基本的增删改查,而这些增删改查代码大 ...

  2. vs code搭建Django环境

    在网上找了很多博客,看了vs code的官方文档,最终拼凑起来,终于搭建起来了djangode开发虚拟环境(win10下) 一.新建项目文件夹 F:\Python\temp\django_demo(例 ...

  3. PHP入门了解

    1.五个基本概念     1.1静态页面和动态页面 静态页面:服务器不执行的页面 动态页面:服务器执行的页面  1.2客户端和服务器端 客户端:浏览器就是客户端 服务器端:给浏览者提供服务  1.3端 ...

  4. Java生鲜电商平台-深入订单拆单架构与实战

    Java生鲜电商平台-深入订单拆单架构与实战 Java生鲜电商中在做拆单的需求,细思极恐,思考越深入,就会发现里面涉及的东西越来越多,要想做好订单拆单的功能,还是相当有难度, 因此总结了一下拆单功能细 ...

  5. JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?

    <JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...

  6. jQuery-File-Upload $(...).fileupload is not a function $.widget is not a function

    使用 jQuery-File-Upload 库的时候碰到了 $(...).fileupload is not a function  和 $.widget is not a function  问题. ...

  7. Gatech OMSCS的申请和学习之奥妙

    https://zhuanlan.zhihu.com/p/54680585 我写东西一向希望能给大家带来正能量,提供有价值的信息,不辱没母校的厚德价值观. 我是传统没落工科毕业后开发软件,但是一直没下 ...

  8. Ubuntu Terminal「控制台」

    nautilus /~ 以窗口形式打开一个文件夹 sudo cp /~ /~ 拷贝文件到指定路径 rm ~ 删除文件 sudo apt-get install –f 依赖 sudo apt-get u ...

  9. postman---post请求数据类型

    我们都知道接口post方法中有不同的请求类型,再写postman中发送请求的时候只是简单的写了一种,今天我们重新了解下Postman如何发送post的其他数据类型 Postman中post的数据类型 ...

  10. luoguP1040 加分二叉树

    在做各类DP的时候都要思路清晰! #include<cstdio> #include<algorithm> using namespace std; const int N = ...