JWT 검증 필터
스프링 시큐리티 filter chain에 요청에 담긴 JWT를 검증하기 위한 커스텀 필터를 등록해야 한다.
해당 필터를 통해 요청 헤더 Authorization 키에 JWT가 존재하는 경우 JWT를 검증하고 강제로 SecurityContextholder에 세션을 생성한다. (이 세션은 STATELESS 상태로 관리되기 때문에 해당 요청이 끝나면 소멸된다.)
JWTFilter 구현
- JWTFilter
public class JWTFilter extends OncePerRequestFilter {
private final JWTUtil jwtUtil;
public JWTFilter(JWTUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//request에서 Authorization 헤더를 찾음
String authorization= request.getHeader("Authorization");
//Authorization 헤더 검증
if (authorization == null || !authorization.startsWith("Bearer ")) {
System.out.println("token null");
filterChain.doFilter(request, response);
//조건이 해당되면 메소드 종료 (필수)
return;
}
System.out.println("authorization now");
//Bearer 부분 제거 후 순수 토큰만 획득
String token = authorization.split(" ")[1];
//토큰 소멸 시간 검증
if (jwtUtil.isExpired(token)) {
System.out.println("token expired");
filterChain.doFilter(request, response);
//조건이 해당되면 메소드 종료 (필수)
return;
}
//토큰에서 username과 role 획득
String username = jwtUtil.getUsername(token);
String role = jwtUtil.getRole(token);
//userEntity를 생성하여 값 set
UserEntity userEntity = new UserEntity();
userEntity.setUsername(username);
userEntity.setPassword("temppassword");
userEntity.setRole(role);
//UserDetails에 회원 정보 객체 담기
CustomUserDetails customUserDetails = new CustomUserDetails(userEntity);
//스프링 시큐리티 인증 토큰 생성
Authentication authToken = new UsernamePasswordAuthenticationToken(customUserDetails, null, customUserDetails.getAuthorities());
//세션에 사용자 등록
SecurityContextHolder.getContext().setAuthentication(authToken);
filterChain.doFilter(request, response);
}
}
SecurityConfig JWTFilter 등록
- SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final AuthenticationConfiguration authenticationConfiguration;
private final JWTUtil jwtUtil;
public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil) {
this.authenticationConfiguration = authenticationConfiguration;
this.jwtUtil = jwtUtil;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf((auth) -> auth.disable());
http
.formLogin((auth) -> auth.disable());
http
.httpBasic((auth) -> auth.disable());
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/login", "/", "/join").permitAll()
.anyRequest().authenticated());
//JWTFilter 등록
http
.addFilterBefore(new JWTFilter(jwtUtil), LoginFilter.class);
http
.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil), UsernamePasswordAuthenticationFilter.class);
http
.sessionManagement((session) -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
}
JWT 요청 인가 테스트
요청 헤더에 JWT 를 첨부하고 로그인할 때 권한이 필요한 페이지에 접근을 진행한다.
참고
https://www.devyummi.com/page?id=668e4e0aa9b1fd82730a94f3
'Spring > Spring Security - JWT' 카테고리의 다른 글
Spring Security JWT 13 : CORS 설정 (0) | 2024.12.21 |
---|---|
Spring Security JWT 12 : 세션 정보 (0) | 2024.12.21 |
Spring Security JWT 10 : 로그인 성공 JWT 발급 (0) | 2024.12.21 |
Spring Security JWT 9 : 발급 및 검증 클래스 (0) | 2024.12.21 |
Spring Security JWT 8 : DB기반 로그인 검증 로직 (1) | 2024.12.21 |