Spring

[Spring] Spring Security 적용하기 + JWT

hah 2025. 7. 4. 11:15

1. 설정

spring security를 사용하기 위해 build.gradle 파일 dependencies 아래에 의존성을 추가해준다.

implementation 'org.springframework.boot:spring-boot-starter-security'

 

 

 

2. JwtFilter 클래스

 

기존에 사용하던 JwtFilter 클래스를 OncePerRequestFilter를 상속받는 클래스로 수정한다.

 

아래의 핵심 코드를 추가하였다.

 

UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                    authUser, "", List.of(new SimpleGrantedAuthority("ROLE_" + userRole.name()))
            );

 

인증 정보를 표현할 때 사용되며, 매개 변수로 보통 유저 정보, 비밀번호, 권한 목록을 담는다.

 

유저정보 - authUser :

코드에서는 Dto를 사용하였으며, 유저 id, 이메일, 역할을 담는다.

 

비밀번호 - "" :

jwt 토큰으로 사용자의 검증이 이미 완료되었기 때문에 별도로 비밀번호를 넣지 않는다.

 

권한 목록 - List.of(new SimpleGrantedAuthority("ROLE_" + userRole.name())) : 

사용자가 가진 권한을 확인한다.

(Spring Security는 권한을 확인할 때 ROLE_ 접두사가 붙은 문자열을 사용하기 때문에 "ROLE_" 접두사를 붙인다.)

 

 

SecurityContextHolder.getContext().setAuthentication(authenticationToken);

 

Spring Security의 현재 보안 컨텍스트(SecurityContext) 를 관리하는 클래스

 

setAuthentication 메서드로 현재 요청의 인증 정보를 설정한다.

(지금 이 사용자(authUser)는 인증된 사용자이며, 특정 권한(ROLE_XXX)을 가지고 있다라고 SecurityContext에 등록하는 것)

 

 

 

3. SecurityConfig 클래스

 

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtUtil jwtUtil;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{

        JwtFilter jwtFilter = new JwtFilter(jwtUtil);

        return httpSecurity
                .csrf(AbstractHttpConfigurer::disable)
                .httpBasic(AbstractHttpConfigurer::disable)
                .formLogin(AbstractHttpConfigurer::disable)
                .addFilterBefore(jwtFilter, SecurityContextHolderAwareRequestFilter.class)
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth/signin", "auth/signup").permitAll()
                        .requestMatchers("/todos/**").hasRole(UserRole.USER.name())
                        .requestMatchers("/admin/**").hasRole(UserRole.ADMIN.name())
                        .requestMatchers("/open").permitAll()
                        .anyRequest().authenticated()
                )
                .build();
    }
}

 

1. @Configuration, @EnableWebSecurity, @RequiredArgsConstructor 어노테이션 추가

 

2. requestMatchers 메서드를 통해 인증 진행할 uri를 선택한 뒤,

permitAll() : 모든 접근 허용

hasRole() : 특정 권한만 접근 허용

authenticated() : 인증된 사용자만 접근 허용

 

 

 

4. TodoController 클래스

 

@PostMapping("/todos")
    public ResponseEntity<TodoSaveResponse> saveTodo(
            @AuthenticationPrincipal AuthUser authUser,
            @Valid @RequestBody TodoSaveRequest todoSaveRequest
    ) {

 

Jwt 필터를 사용할 때는 @Auth 어노테이션을 사용해서 인증된 유저 정보를 받아왔지만,

Spring Security를 사용할 때는 @AuthenticationPrincipal 어노테이션을 사용해서 인증된 유저 정보를 받아온다.