Table of Contents
Spring Boot Cache for Authorization Server
목표
Authorization Server 에 Cache 를 적용합니다.
build.gradle 수정
redis 는 미리 설치되어 있어야 합니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-cache'
// ......
}
파일추가
캐시를 활성화 합니다.
CacheConfig.java
@Configuration
@EnableCaching
public class CacheConfig {
}
RedisConfig.java
@RequiredArgsConstructor
@Configuration
public class RedisConfig {
private final RedisProperties redisProperties;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
}
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
application.yml 수정
spring:
redis:
cluster:
nodes: 127.0.0.1:6379
캐시를 붙이기 위해, JdbcClientDetailsService
를 확장합니다.
CustomJdbcClientDetailsService.java
@Service
public class CustomJdbcClientDetailsService extends JdbcClientDetailsService {
public CustomJdbcClientDetailsService(DataSource dataSource) {
super(dataSource);
}
@Override
@Transactional(readOnly = true)
@Cacheable(value="clientId")
public ClientDetails loadClientByClientId(String clientId) throws InvalidClientException {
// System.out.println("1111111111111111111");
return super.loadClientByClientId(clientId);
}
@Override
@Transactional
@CacheEvict(value="clientId", key="#clientDetails.getClientId()")
public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
super.updateClientDetails(clientDetails);
}
@Override
@Transactional
@CacheEvict(value="clientId", key="#clientId")
public void updateClientSecret(String clientId, String secret) throws NoSuchClientException {
super.updateClientSecret(clientId, secret);
}
@Override
@Transactional
@CacheEvict(value="clientId")
public void removeClientDetails(String clientId) throws NoSuchClientException {
super.removeClientDetails(clientId);
}
}
CustomJdbcClientDetailsService
를 붙여줍니다.
@RequiredArgsConstructor
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
// ......
private final CustomJdbcClientDetailsService clientDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
clients.withClientDetails(clientDetailsService);
}
// ......
}
한 번의 액세스토큰을 얻기위해 13번의 loadClientByClientId
호출이 모두 사라집니다.
C:\Program Files\Redis>redis-cli
127.0.0.1:6379> keys *
1) "clientId::foo"
2) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:110968452271843970018"
127.0.0.1:6379>
127.0.0.1:6379> get clientId::foo
"\xac\xed\x00\x05sr\x00Eorg.springframework.security.oauth2.provider.cl...
.........................
clientId::foo
가 redis
에 저장되어 있는 것을 확인할 수 있습니다.
Pingback: Spring Boot OAuth2 Authorization Server 구축 – 상구리의 기술 블로그