写在前边

本文对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. MongoDB for OPS 01:服务介绍与基本使用

    写在前面的话 数据库产品已经学习了两个,MySQL 和 Redis.接下来开始研究另外一款 NoSQL 产品 MongoDB,注意跟芒果没啥关系.该产品对于运维来说,相对于操作少一些. 关于 Mong ...

  2. Python【day 13】内置函数02

    一.作用域相关-2个 1.locals() 参数是空 返回当前位置作用域的所有变量,返回的是字典 当前位置:函数内,返回局部变量 当前位置:函数外,返回全局变量 2.globals() 参数是空 返回 ...

  3. String字符串工具类

    字符串类(StringUtil.cs) using System; namespace Sam.OA.Common { /// <summary> /// 字符处理工具类 /// 作者:陈 ...

  4. c# 打印的问题总结

    近期 做了一个打印的类,有一下功能: /// <summary>    /// 打印数据表格的类    /// 2016/05/19 @佳序    /// 功能:    /// 01.自动 ...

  5. 微服务:Eureka+Zuul+Ribbon+Feign+Hystrix构建微服务架构

    原文地址:http://blog.csdn.net/qq_18675693/article/details/53282031 本案例将打架一个微服务框架,参考来源官方参考文档 微服务:是什么?网上有一 ...

  6. 【mysql】pymysql.err.InterfaceError Interface Error: (0, '')

    八成是丢失连接了 while 1: try: self.conn.ping(reconnect=True) self.cur.execute(sql,tuple(item.values())) sel ...

  7. springboot 使用 jedis 连接 Redis 数据库

    1. 在 pom.xml 配置文件中添加依赖 <!-- redis 依赖 --> <dependency> <groupId>org.springframework ...

  8. ssh-agent,ssh-add 命令

    centos 6.9 下测试: ssh-agent是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管. eval `ssh-agent -s` ssh-a ...

  9. 03webpack--输入webpack--自动打包

    如何实现时时跟新我写的代码 此时就需要有一个配置文件了 webpack.config.js这个文件 这个文件是在跟目录下哦 webpack是基于node去构建的 所以你的依法和node还是很相似的哦 ...

  10. PHP 自动加载

    回顾 开始的时候, 如果想在一个php文件中使用其它文件的类或方法, 需要通过include/require方法将文件包含进来. 这种方法的缺点也很明显: 如果需要引入很多文件, 就需要很多的incl ...