Spring cloud security Oauth2 多节点集群需要修改的配置

来源:互联网 发布:水杯推荐 知乎 编辑:程序博客网 时间:2024/06/03 16:08

最近在学习Spring cloud微服务的搭建,采用Spring 的 OAuth2作为单点登录服务器,通过zuul作统一路由,所以认证服务 (Authentication Server)端可通过多实例进行集群部署,集群部署时需要对认证服务 (Authentication Server)进行如下几点配置。

1、通过redis存储AccessToken

@Configurationpublic class AuthServerConfig extends AuthorizationServerConfigurerAdapter {        @Autowiredprivate AuthenticationManager authenticationManager;        @Autowiredprivate RedisConnectionFactory redisConnectionFactory;        @Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter());endpoints.tokenStore(tokenStore());}@Beanpublic TokenStore tokenStore() {return new RedisTokenStore(redisConnectionFactory);}}

2、共享Authentication code

目前spring提供了内存和数据库两种方式存储授权码Authentication code,要实现多个实例之间共享可以选在将AuthenTicationCode存储在数据中,相关配置为

        @Beanpublic AuthorizationCodeServices authorizationCodeServices(){return new JdbcAuthorizationCodeServices(dataSource);}        @Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter());endpoints.tokenStore(tokenStore());endpoints.authorizationCodeServices(authorizationCodeServices());}
需要在数据库中创建表 auth_code

CREATE TABLE `oauth_code` (  `code` varchar(1024) DEFAULT NULL,  `authentication` blob)
我们也可以自定义AuthorizationCodeServices实现类来将auth_code 存放在redis中

public class RedisAuthenticationCodeServices extends RandomValueAuthorizationCodeServices {private static Logger log = Logger.getLogger(RedisAuthenticationCodeServices.class);private static final String AUTH_CODE_KEY = "auth_code";private RedisConnectionFactory connectionFactory;public RedisAuthenticationCodeServices(RedisConnectionFactory connectionFactory) {Assert.notNull(connectionFactory, "RedisConnectionFactory required");this.connectionFactory = connectionFactory;}@Overrideprotected OAuth2Authentication remove(String code) {RedisConnection conn = getConnection();try {OAuth2Authentication authentication = null;try {authentication = SerializationUtils.deserialize(conn.hGet(AUTH_CODE_KEY.getBytes("utf-8"), code.getBytes("utf-8")));} catch (Exception e) {return null;}if (null != authentication) {conn.hDel(AUTH_CODE_KEY.getBytes("utf-8"), code.getBytes("utf-8"));}return authentication;} catch (Exception e) {return null;} finally {conn.close();}}@Overrideprotected void store(String code, OAuth2Authentication authentication) {RedisConnection conn = getConnection();try {conn.hSet(AUTH_CODE_KEY.getBytes("utf-8"), code.getBytes("utf-8"),SerializationUtils.serialize(authentication));} catch (Exception e) {log.error("保存authentication code 失败", e);} finally {conn.close();}}private RedisConnection getConnection() {return connectionFactory.getConnection();}}

3、共享session

OAuth2服务在申请授权码时会先判断用户是否登录,如未登录则会引导到登录页面,所以我们需要在不同实例之间共享session,我么可以通过Spring的Session很容易的实现session共享。首先引入jar包,maven的配置如下

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session</artifactId></dependency>
通过@EnableRedisHttpSession注解开启session共享。




阅读全文
0 0