写在前边

本文对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. layui 使用随记

    layui confir使用 不显示右上角关闭按钮 针对提示框内按钮指定操作 layer.confirm("这里填写提示信息", {closeBtn:0,icon: 0, titl ...

  2. django实现客户端文件下载

    基于django项目,由于不是专门讲文件的下载,这里仅是项目需要,所以可能不是特别的详细.仅做流程的演示: 实现过程: 1.准备下载url # 下载文件 url(r'^download_file/$' ...

  3. PLSQL 12 安装、连接Oracle

    点击下载PLSQL,本次安装的PLSQL版本为12.0.7,建议安装64位. 下载PLSQL时,版本旁边会有个“Language pack”的链接,点击后左侧选择“Chinese”即可下载汉化包. 注 ...

  4. contentOffset、contentSize和contentInset

    1.UIScrollView@property(nonatomic)CGPoint contentOffset;这个属性用来表示UIScrollView滚动的位置 @property(nonatomi ...

  5. python基础 while 字符串方法 运算符

    一.while 1.while 死循环 f=True while f: print(1) print(2) 2.while 活循环 ①.正序 count = 1 while count <= 5 ...

  6. Mysql—修改用户密码(重置密码)

    1.登录mysql [root@localhost ~]# mysql -uroot -p123456 [root@localhost ~]# mysql -hlocalhost -uroot -p1 ...

  7. [视频教程] 基于redis的消息队列实现与思考

    使用redis的list列表来实现消息队列功能,相信大家都听过消息队列,但是在业务中可能并没有真正去使用它.在公司项目中正好有个场景使用到了消息队列,因此就来说一下流程.在web界面上有个功能是群发邮 ...

  8. java面试填坑解惑篇

    感谢原文出处:https://www.cnblogs.com/javazhiyin/ NO1.请简单描述JDK和JRE的区别? NO1.回答JDK和JRE的区别这道题,首先要回答两个名次的概念,JDK ...

  9. 201271050130-滕江南《面向对象程序设计(java)》第十一周学习总结

    项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/ ...

  10. 鲜贝7.3--Xshell安装

    安装包百度云下载地址:https://blog.csdn.net/yueruitao/article/details/85263968 具体方法请参考: https://blog.csdn.net/q ...