Spring Boot Cache for Authorization Server

By | 2021년 7월 29일
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::fooredis 에 저장되어 있는 것을 확인할 수 있습니다.

One thought on “Spring Boot Cache for Authorization Server

  1. Pingback: Spring Boot OAuth2 Authorization Server 구축 – 상구리의 기술 블로그

답글 남기기