spring boot oauth2单点登录(四)code存储方

2021-10-13  本文已影响0人  樱花舞

相关文章

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);
    }
上一篇下一篇

猜你喜欢

热点阅读