Spring security를 써봅시다

Jiyeong Kim·2025년 3월 17일

TIL

목록 보기
23/24

문제

Spring Security를 도입하기로 결정했어요!

  • 기존 FilterArgument Resolver를 사용하던 코드들을 Spring Security로 변경해주세요.
    • 접근 권한 및 유저 권한 기능은 그대로 유지해주세요.
    • 권한은 Spring Security의 기능을 사용해주세요.
  • 토큰 기반 인증 방식은 유지할 거예요. JWT는 그대로 사용해주세요.

Spring Security 공식 문서

Spring Security 란?

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security는 강력하고 고도로 사용자 정의 가능한 인증 및 액세스 제어 프레임워크입니다. Spring 기반 애플리케이션을 보호하기 위한 사실상의 표준입니다.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

Spring Security는 Java 애플리케이션에 인증과 권한 부여를 모두 제공하는 데 중점을 둔 프레임워크입니다. 모든 Spring 프로젝트와 마찬가지로 Spring Security의 진정한 힘은 사용자 정의 요구 사항을 충족하도록 얼마나 쉽게 확장할 수 있는지에 있습니다.

Features

  • Comprehensive and extensible support for both Authentication and Authorization
    (인증 및 권한 부여에 대한 포괄적이고 확장 가능한 지원)
  • Protection against attacks like session fixation, clickjacking, cross site request forgery, etc
    (세션 고정, 클릭재킹, 크로스 사이트 요청 위조 등과 같은 공격으로부터 보호)
  • Servlet API integration
    (서블릿 API 통합)
  • Optional integration with Spring Web MVC
    (Spring Web MVC와의 선택적 통합)

출처: 공식문서

자세한 구조는 아무리 강의나 문서를 봐도 이해가 잘 되지 않았기 때문에.. 대충 인증 인가와 관련한 거구나~ 하고 넘어가겠다. 직접 해봐야지..

Spring Security 적용하기


위의 overview에서 시키는 대로 servlet을 누르면

Getting Started <<<요 hello spring security 페이지가 나온다.

1. Updating Dependencies 의존성 주입

maven 또는 Gradle 중에서 선택하면 되는데, 나는 gradle이니까 build.gradle에 다음의 의존성을 추가해주었다.

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-security"
}

공식문서에는 아래에 BOM을 사용하여 버전을 관리할 수 있는 코드도 제공하고 있는데, 기본적으로 Spring boot가 버전 관리를 해주기 때문에 굳이 사용할 필요는 없다.

2. Spring Security 에 필요한 SecurityConfig, Filter 파일 셋팅

1) SecurityConfig

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {

	private final JwtRequestFilter jwtRequestFilter;
  • @Bean으로 SecurityFilterChain 주입 -> 보안기능
  • AuthenticationManager를 Spring Bean으로 등록

2) JwtRequestFilter

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtRequestFilter extends OncePerRequestFilter { 

    private final JwtUtil jwtUtil;
  • @Override로 jwt 추출 및 가공

3. JwtUtil에 추출 관련 메서드 추가

public Long extractUserId(String token) {
        Claims claims = extractClaims(token); //jwt 파싱
        String subject = claims.getSubject();
        return Long.parseLong(subject); //long -> userId로 변환
    }
    

4. 각 클래스의 jwt 사용 인증 부분을 Spring security를 활용하도록 수정

  • @Auth AuthUser authUser -> Principal principal
public CommentSaveResponse saveComment(Principal principal, long todoId, CommentSaveRequest commentSaveRequest) {

         Long userId = Long.valueOf(principal.getName()); // 회원 id 가공
         User user = userRepository.findById(userId)
             .orElseThrow(() -> new InvalidRequestException("User not found"));

트러블 슈팅

오류 메세지:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "filter" is null

원인1: jwtRequestFilter 주입 안됨

private JwtRequestFilter jwtRequestFilter;

해결 방법:

private final JwtRequestFilter jwtRequestFilter;

원인2: securityException 기입 오류

  • 오타, 또는 expiredJwtException 위치에 securityException 기입함
profile
해봅시다

0개의 댓글