일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Apple 로그인
- REDIS
- FeignClients
- 쿼리 메소드
- microsoft
- StringCacheKeyGenerator
- OpenFeign
- OAuth2.0
- CHAR 와 VARCHAR
- async 와 await
- 오블완
- 비식별
- Spring Reactive Programming
- 비사이드프로젝트
- querydsl
- asciidoctor
- springboot
- 네이버클라우드 서버
- 코드로 배우는 스프링 부트 웹 프로젝트
- INSERT ON DUPLICATE KEY UPDATE
- ExceptionHandlerFilter
- JWT
- 사이드 프로젝트
- 티스토리챌린지
- rest docs
- spring boot
- 2024년 상반기 회고
- Spring Security
- 도메인 주도 설계(DDD) 기반 마이크로서비스(MSA) 모델링
- Spring Cloud OpenFeign
- Today
- Total
기록하기
ExceptionHandlerFilter 적용(1) 본문
Spring Security + JWT 를 적용한 프로젝트에서 토큰을 검증할 때 만료된 토큰이거나 유효성 검증에서 실패할 경우 Exception 처리를 하게 된다. 하지만 Exception 처리 이후 재로그인을 하도록 유도하기 위해 alert 을 줘야하는데 이 과정에서 프론트 개발자에게 해당 메세지를 전달해야하기에 단순히 Exception 처리만 하는 것으로는 해결할수가 없었다. 특히나 Filter 처리 과정에서 발생하는 에러이기에 처리를 위해서는 다른 설계가 필요하다고 판단되어 찾아본 결과 ExceptionHandlerFilter 를 커스텀하여 생성한 뒤 SecurityConfig 에 설정을 해주면 된다고 하여 설정을 해보았다.
1. Security Configuration 적용 및 flow 설계
2. Spring Security + JWT + Redis 설정 및 진행 과정
Security Configuration 적용 및 flow 설계
먼저, 다음과 같은 flow 로 설계를 하였다.
어떤 request 가 들어올 때마다 CustomAuthenticationFilter 에서 요청을 먼저 처리하게 된다. 이때, 헤더에서 꺼내온 토큰이 redis 에서 찾은 토큰과 일치하고 유효할 때 다음 Filter 과정을 거칠 수 있게 된다. 하지만 이 과정에서 유효성 검증에 실패하게 되면 Exception 을 터뜨리는데 이때 ExceptionHandlerFilter 가 그 Exception 을 받아서 처리하는 역할을 한다.
또한 로그인의 경우에는 CustomLoginProcessingFilter 가 로그인 절차를 처리하도록 설계했다. 예를 들어 /login url 으로 접근하게 되면 로그인이 진행되는 것이며 이 Filter 안에서 처리를 하게 된다. 이때는 토큰이 없지만 받아 온 로그인 정보가 DB 에 있는지 검사하여 이 과정에서 문제가 발생하게 되면 Exception 을 던지게 된다. 이 역시 ExceptionHandlerFilter 가 그 Exception 을 받아서 처리하는 것이다.
그렇다면, 이를 SecurityConfig 에서 어떻게 설계를 하면 되는걸까?
필터 처리의 순서만 본다면 아래와 같이 작성할 수 있다. (그 외 설정은 아주 기본적인 것만 해 둔 상태이며 2. Spring Security + JWT + Redis 설정 및 진행 과정 을 작성하며 상세하게 설명하도록 하겠다.)
@Slf4j
@Order(0)
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomLoginProcessingFilter customLoginProcessingFilter;
private final CustomAuthenticationFilter customAuthenticationFilter;
private final CustomExceptionHandlerFilter customExceptionHandlerFilter;
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1")
.password("$2a$10$lwQSzZIweS0rxglCDLETtuHvGMFMdFmf6Y/ySZkeUkWk4VTZkY.Ya") //qwer1234@
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().permitAll()
.and()
.exceptionHandling()
// .authenticationEntryPoint()
// .accessDeniedHandler()
.and()
.csrf().disable()
.cors().disable()
.formLogin()
.loginProcessingUrl("/login");
http.addFilterBefore(customLoginProcessingFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(customAuthenticationFilter, CustomLoginProcessingFilter.class)
.addFilterBefore(customExceptionHandlerFilter, CustomAuthenticationFilter.class);
}
}
가장 아래 addFilterBefore 을 보게 되면,
지정된 필터 앞에 커스텀 필터를 추가하여 UsernamePasswordAuthenticationFilter 보다 CustomLoginProcessingFilter 를 먼저 실행하겠다는 의미를 나타낸다.
이렇게 설정을 해줌으로써 위 설계대로 진행을 할 수 있게 된다.
세부적인 토큰의 유효성 검증과 redis, Exception 처리는 다음 블로그에서 작성하도록 하겠다.
'Server > Spring Boot' 카테고리의 다른 글
EhCache - StringCacheKeyGenerator 사용 시 @Cacheable 적용 (0) | 2022.09.18 |
---|---|
logback 설정 - 특정 변수에 따라 log 파일 다른 위치에 저장하기 (0) | 2022.08.25 |
ExceptionHandlerFilter 적용(3) (0) | 2022.07.10 |
ExceptionHandlerFilter 적용(2) (0) | 2022.07.03 |
Controller 테스트 시 인증 정보 주입(Spring Security + JWT) (0) | 2022.05.08 |