升级access_token, refresh_token为JWT(Json Web Token), 提高性能

2.1.0
mkk 2020-06-09 23:50:53 +08:00
parent 6ad88506e8
commit d15cc67463
6 changed files with 204 additions and 9 deletions

View File

@ -0,0 +1,78 @@
package com.monkeyk.sos.config;
import com.monkeyk.sos.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
/**
* 2020/6/9
* <p>
* <p>
* JWT TokenStore config
*
* @author Shengzhao Li
* @since 2.1.0
*/
@Configuration
@ConditionalOnProperty(name = "sos.token.store", havingValue = "jwt")
public class JWTTokenStoreConfiguration {
/**
* HMAC key, default: IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa
* alg: HMACSHA256
*/
@Value("${sos.token.store.jwt.key:IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa}")
private String jwtKey;
@Bean
public JwtAccessTokenConverter accessTokenConverter(UserService userService) {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
DefaultUserAuthenticationConverter userAuthenticationConverter = new DefaultUserAuthenticationConverter();
userAuthenticationConverter.setUserDetailsService(userService);
// userAuthenticationConverter.setDefaultAuthorities(new String[]{"USER"});
tokenConverter.setUserTokenConverter(userAuthenticationConverter);
tokenConverter.setIncludeGrantType(true);
// tokenConverter.setScopeAttribute("_scope");
jwtAccessTokenConverter.setAccessTokenConverter(tokenConverter);
jwtAccessTokenConverter.setSigningKey(this.jwtKey);
return jwtAccessTokenConverter;
}
/**
* JWT TokenStore
*
* @since 2.1.0
*/
@Bean
public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
return new JwtTokenStore(jwtAccessTokenConverter);
}
@Bean
public DefaultTokenServices tokenServices(TokenStore tokenStore, JwtAccessTokenConverter tokenEnhancer, ClientDetailsService clientDetailsService) {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setClientDetailsService(clientDetailsService);
//support refresh token
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenEnhancer(tokenEnhancer);
return tokenServices;
}
}

View File

@ -0,0 +1,46 @@
package com.monkeyk.sos.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import javax.sql.DataSource;
/**
* 2020/6/9
* <p>
* <p>
* JDBC TokenStore config
*
* @author Shengzhao Li
* @since 2.1.0
*/
@Configuration
@ConditionalOnProperty(name = "sos.token.store", havingValue = "jdbc", matchIfMissing = true)
public class JdbcTokenStoreConfiguration {
/**
* JDBC TokenStore
*/
@Bean
public TokenStore tokenStore(DataSource dataSource) {
return new JdbcTokenStore(dataSource);
}
@Bean
public DefaultTokenServices tokenServices(TokenStore tokenStore, ClientDetailsService clientDetailsService) {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setClientDetailsService(clientDetailsService);
//support refresh token
tokenServices.setSupportRefreshToken(true);
return tokenServices;
}
}

View File

@ -26,8 +26,8 @@ import org.springframework.security.oauth2.provider.approval.UserApprovalHandler
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import javax.sql.DataSource;
@ -116,6 +116,9 @@ public class OAuth2ServerConfiguration {
@Autowired
private TokenStore tokenStore;
@Autowired
private DefaultTokenServices tokenServices;
@Autowired
private ClientDetailsService clientDetailsService;
@ -145,13 +148,13 @@ public class OAuth2ServerConfiguration {
}
/*
* JDBC TokenStore
*/
@Bean
public TokenStore tokenStore(DataSource dataSource) {
return new JdbcTokenStore(dataSource);
}
// /*
// * JDBC TokenStore
// */
// @Bean
// public TokenStore tokenStore(DataSource dataSource) {
// return new JdbcTokenStore(dataSource);
// }
/*
* Redis TokenStore (Redis使)
@ -179,7 +182,8 @@ public class OAuth2ServerConfiguration {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
endpoints.tokenServices(tokenServices)
.tokenStore(tokenStore)
.authorizationCodeServices(authorizationCodeServices)
.userDetailsService(userDetailsService)
.userApprovalHandler(userApprovalHandler())

View File

@ -1,9 +1,13 @@
package com.monkeyk.sos.web.context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.util.Assert;
/**
@ -18,6 +22,7 @@ import org.springframework.util.Assert;
*/
public class SOSContextHolder implements BeanFactoryAware, InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(SOSContextHolder.class);
/**
* @since 2.1.0
@ -25,6 +30,13 @@ public class SOSContextHolder implements BeanFactoryAware, InitializingBean {
private static BeanFactory beanFactory;
/**
* @since 2.1.0
*/
@Value("${spring.application.name:spring-oauth-server}")
private String applicationName;
public SOSContextHolder() {
}
@ -69,6 +81,11 @@ public class SOSContextHolder implements BeanFactoryAware, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(beanFactory, "beanFactory is null");
if (LOG.isDebugEnabled()) {
TokenStore tokenStore = getBean(TokenStore.class);
LOG.debug("{} use tokenStore: {}", this.applicationName, tokenStore);
}
}
}

View File

@ -41,4 +41,10 @@ spring.main.allow-bean-definition-overriding=true
#spring.redis.password=
#spring.redis.timeout=2000
#spring.redis.ssl=false
#
# Condition Config
# @since 2.1.0
# 配置使用什么类型 TokenStore,支持 jdbc, jwt
sos.token.store=jwt

View File

@ -0,0 +1,44 @@
package com.monkeyk.sos.config;
import org.junit.Test;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import java.util.Map;
import static org.junit.Assert.*;
/**
* 2020/6/9
*
* @author Shengzhao Li
* @since 2.1.0
*/
public class JWTTokenStoreConfigurationTest {
@Test
public void keyTest() throws Exception {
RandomValueStringGenerator randomValueStringGenerator = new RandomValueStringGenerator(32);
String verifierKey = randomValueStringGenerator.generate();
assertNotNull(verifierKey);
// System.out.println(verifierKey);
}
@Test
public void testJwtAccessTokenConverter() throws Exception {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa");
jwtAccessTokenConverter.afterPropertiesSet();
assertFalse(jwtAccessTokenConverter.isPublic());
Map<String, String> key = jwtAccessTokenConverter.getKey();
assertNotNull(key);
}
}