前言
上一篇文章Spring Cloud进阶之路 | 十九:授权服务(Spring Cloud Oauth2)TokenStore之JdbcTokenStore中,介绍了如何配置JdbcTokenStore,将token等信息存储在数据库中。数据库有其限制性,一旦数据量过大,那么新增、更新、查询等操作的速率将会大幅下降,这时,就需要缓存支持,框架为我们提供了Redis存储方式,即RedisTokenStore,本文即针对此种存储形式进行简单介绍。
准备工作
复用上一篇文章Spring Cloud进阶之路 | 十九:授权服务(Spring Cloud Oauth2)TokenStore之JdbcTokenStore中的xmall-atuh授权服务工程,并进行相关改造。
另外,需要准备redis环境,笔者安装了windows平台的redis服务,并在6379端口启动成功。
配置
通过方法public void configure(ClientDetailsServiceConfigurer clients) throws Exception配置TokenStore。
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(new RedisTokenStore(redisConnectionFactory));
;
}
完整配置如下。
package com.luas.xmall.auth.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.builders.JdbcClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import javax.sql.DataSource;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.
allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()")
;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(new RedisTokenStore(redisConnectionFactory));
;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 配置方法1,只需配置DataSource即可,其它交给框架自动配置
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
// 配置方法2,构建ClientDetailsServiceBuilder
//clients.configure(jdbcClientDetailsServiceBuilder());
// 配置方法3,使用ClientDetailsServiceBuilder构建ClientDetailsService
//clients.withClientDetails(jdbcClientDetailsService());
// 配置方法4,自定义ClientDetailsService
//clients.withClientDetails(myClientDetailsService());
}
private JdbcClientDetailsServiceBuilder jdbcClientDetailsServiceBuilder() {
return new JdbcClientDetailsServiceBuilder().dataSource(dataSource).passwordEncoder(passwordEncoder);
}
private ClientDetailsService jdbcClientDetailsService() throws Exception {
return new JdbcClientDetailsServiceBuilder().dataSource(dataSource).passwordEncoder(passwordEncoder).build();
// 直接构建JdbcClientDetailsService对象
// JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
// jdbcClientDetailsService.setPasswordEncoder(passwordEncoder);
// return jdbcClientDetailsService;
}
public ClientDetailsService myClientDetailsService() throws Exception {
return new ClientDetailsService() {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
// TODO 调用dao、service查询自定义数据结构、库,组织对应的ClientDetails
return null;
}
};
}
}
验证
启动xmall-auth工程,端口为7777。
访问http://localhost:7777/oauth/token,输入一众参数,诸如client_id、client_secret、grant_type等,点击Send,即出现access_token、refresh_token等信息。
查看redis缓存库,已存储该token的相关信息。
仔细查看相关key值,access_token、refresh_token存储key值,与其参数值一致。
源码
github
https://github.com/liuminglei/SpringCloudLearning/tree/master/20/
gitee
https://gitee.com/xbd521/SpringCloudLearning/tree/master/20/
本文系【银河架构师】原创,如需转载请在文章明显处注明作者及出处。
微信搜索【银河架构师】,发现更多精彩内容。