Client
✅ JWT
-> JwtFilter
-> Spring Security Filter Chain
-> Controller
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/users", "/api/auth/login").permitAll()
.anyRequest().authenticated()
)
Long userId = jwtUtil.extractUserId(token);
String username = jwtUtil.extractUsername(token);
UserRole role = jwtUtil.extractUserRole(token);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
Spring Security에서 사용자의 세부 정보를 담는 인터페이스
주로 사용자 이름, 비밀번호, 권한 등의 정보를 제공
//Controller에서 사용 가능 null이 아님
@AuthenticationPrincipal UserinfoDetails user
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtFilter jwtFilter;
private final CustomUserDetailService customUserDetailService;
private final CustomAccessDeniedHandler customAccessDeniedHandler;
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.userDetailsService(customUserDetailService)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling(e ->
e.authenticationEntryPoint(customAuthenticationEntryPoint)
.accessDeniedHandler(customAccessDeniedHandler)
)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/users", "/api/auth/login").permitAll()
.anyRequest().authenticated()
)
.build();
}
}
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader == null || !authorizationHeader.startsWith(BEARER_PREFIX)) {
filterChain.doFilter(request, response);
return;
}
String token = authorizationHeader.substring(7);
if (!jwtUtil.validateToken(token)) {
filterChain.doFilter(request, response);
return;
}
Long userId = jwtUtil.extractUserId(token);
String username = jwtUtil.extractUsername(token);
UserRole role = jwtUtil.extractUserRole(token);
UserinfoDetails userDetails = new UserinfoDetails(userId, username, role);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
}
| 역할 | 하는 곳 |
|---|---|
| 로그인 | Controller, Service |
| JWT 발급 | Service, Util |
| JWT 검증 | JwtFilter |
| 인증 객체 저장 | SecurityContextHolder |
| 인가 | SpringSecurity |
| 세부 정보 | UserDetails |