[Spring] @AuthenticationPrincipal null

2023. 1. 12. 09:24·Spring

문제상황

@PostMapping()
public ResponseEntity<? extends BaseResponseBody> createConference(@AuthenticationPrincipal SsafyUserDetails userDetails) {
    conferenceService.createConference(userDetails.getUser().getUserId());
    return ResponseEntity.status(201).body(BaseResponseBody.of(201, "Success"));
}

프로젝트를 진행할 때 SpringSecurity와 JWT Token 기술이 적용된 스켈레톤 코드를 받아서 진행하는데 늘 사용하던 @AuthenticationPrincipal 어노테이션을 사용하니 UserDetails 인터페이스를 구현한 클래스가 계속 null 값이 떴다. 

문제원인

사용자 요청이 들어오면 AuthenticationFilter가 요청을 가로챈 후 getAuthentication() 메서드로 UsernamePasswordAuthenticationToken 객체를 생성하는데 이때 토큰의 파라미터로 String 값인 userId를 넣어준 것이 원인이었다.

/**
 * 요청 헤더에 jwt 토큰이 있는 경우, 토큰 검증 및 인증 처리 로직 정의.
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
    ...

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ...

        try {
            Authentication authentication = getAuthentication(request);
            // jwt 토큰으로 부터 획득한 인증 정보(authentication) 설정.
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } 

        ...
    }

    @Transactional(readOnly = true)
    public Authentication getAuthentication(HttpServletRequest request) throws Exception {
        ...
        
        // 식별된 정상 유저인 경우, 요청 context 내에서 참조 가능한 인증 정보(jwtAuthentication) 생성.
        SsafyUserDetails userDetails = new SsafyUserDetails(user);
        UsernamePasswordAuthenticationToken jwtAuthentication = new UsernamePasswordAuthenticationToken(userId,
                null, userDetails.getAuthorities());
                
        ...
    }
}

해결방법

아래와 같이 첫번째 파라미터인 userId를 UserDetails 인터페이스를 구현한 클래스로 바꿔주었더니 UserDetails 구현클래스가 잘 넘어온 것을 확인할 수 있었다.

@Transactional(readOnly = true)
public Authentication getAuthentication(HttpServletRequest request) throws Exception {
    ...

    // 식별된 정상 유저인 경우, 요청 context 내에서 참조 가능한 인증 정보(jwtAuthentication) 생성.
    SsafyUserDetails userDetails = new SsafyUserDetails(user);
    UsernamePasswordAuthenticationToken jwtAuthentication = new UsernamePasswordAuthenticationToken(userDetails,
            null, userDetails.getAuthorities());

    ...
}

 

'Spring' 카테고리의 다른 글

[Spring] ThreadLocal이란?  (0) 2023.03.08
[Spring] Interceptor와 ServletFilter의 차이  (0) 2023.03.07
동시성 이슈 해결방법 (Synchronized, DB Lock, Redis Lock)  (0) 2022.12.20
리팩토링  (1) 2022.12.02
[Spring] 스프링 빈 설정 (XML, JAVA, Component Scan)  (0) 2022.11.08
'Spring' 카테고리의 다른 글
  • [Spring] ThreadLocal이란?
  • [Spring] Interceptor와 ServletFilter의 차이
  • 동시성 이슈 해결방법 (Synchronized, DB Lock, Redis Lock)
  • 리팩토링
kiyoom
kiyoom
  • kiyoom
    Keylog
    kiyoom
  • 전체
    오늘
    어제
    • 분류 전체보기 (71)
      • Git (2)
      • Java (16)
      • 네트워크 (7)
      • 알고리즘 (0)
      • Spring (26)
      • JPA (14)
      • DB (3)
      • Server (3)
      • 기타 (0)
      • Kotlin (0)
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
kiyoom
[Spring] @AuthenticationPrincipal null
상단으로

티스토리툴바