spring boot oauth2单点登录(四)code存储方
相关文章
1、spring boot oauth2单点登录(一)-前后端分离例子
2、spring boot oauth2单点登录(二)-客户端信息存储
3、spring boot oauth2单点登录(三)-token存储方式
4、spring boot oauth2单点登录(四)-code存储方式
源码地址
后端:https://gitee.com/fengchangxin/sso
前端:https://gitee.com/fengchangxin/sso-page
准备
后端:三个spring boot应用,auth(授权管理),client1(客户端应用1),client2(客户端应用2)。
前端:三个Vue项目,auth,client1,client2。分别对应三个后端应用。
工具:nginx
域名:oauth.com,client1.com,client2.com,分别对应三个系统。
开发环境:先在host文件添加上面三个域名。
端口:
后端服务auth(8080),client1(8081),client2(8082)。
前端auth(8083),client1(8084),client2(8085)。
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
测试地址:
client1:http://client1.com/client1Page/#/home
client2:http://client2.com/client2Page/#/home
登录用户:admin/123456
备注:此篇文章对应的授权管理应用:auth-code
授权码code存储
框架默认存储在内存(InMemoryAuthorizationCodeServices),单机应用没问题,若应用是集群部署,就可能会出现问题。而框架已经提供了两种实现方式:内存(InMemoryAuthorizationCodeServices),数据库(JdbcAuthorizationCodeServices)。
1.1数据库存储(JdbcAuthorizationCodeServices)
首先先建好oauth_code表,然后在AuthorizationServerEndpointsConfigurer配置就可以了,注意的是在测试时oauth_code的数据再验证完之后会被删除,当看到表中没数据时并不是配置不生效,而是被删除了,可以debug来跟踪。
@Autowired
private DataSource dataSource;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory));
endpoints.authorizationCodeServices(new JdbcAuthorizationCodeServices(dataSource));
}
1.2自定义
如果不想存在数据库,或者不想用默认的数据库表,那也可以继承RandomValueAuthorizationCodeServices类,来实现自定义。例如下面例子使用Redis来存储:
@Service
public class CodeStoreService extends RandomValueAuthorizationCodeServices {
@Autowired
private RedisTemplate redisTemplate;
private static final String CODE_KEY = "auth:code:%s";
/**
* 存储code
*
* @param code
* @param authentication
*/
@Override
protected void store(String code, OAuth2Authentication authentication) {
String key = String.format(CODE_KEY, code);
System.out.println("保存code:" + code);
//保存30分钟
redisTemplate.opsForValue().set(key, SerializationUtils.serialize(authentication), 30, TimeUnit.MINUTES);
}
/**
* 删除code
*
* @param code
* @return
*/
@Override
protected OAuth2Authentication remove(String code) {
String key = String.format(CODE_KEY, code);
Object value = redisTemplate.opsForValue().get(key);
if (value != null) {
System.out.println("删除code:" + code);
redisTemplate.delete(key);
return SerializationUtils.deserialize((byte[]) value);
}
return null;
}
}
在AuthorizationServerEndpointsConfigurer配置自定义类。
//redis存储
@Autowired
private CodeStoreService codeStoreService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory));
endpoints.authorizationCodeServices(codeStoreService);
}