[Security] SecurityContext의 사용자 인증 정보 가져오기

손은실·2024년 8월 20일
0

Spring Boot

목록 보기
3/13
post-thumbnail
post-custom-banner

이슈 배경

Spring Security 폼 로그인을 통해 사용자 인증을 수행했습니다.
로그인에 성공한 사용자의 정보는 Spring Security에 의해 별도의 저장소에 보관됩니다.

그러나, Spring Security가 사용자의 정보를 가지고 있음에도 불구하고, Controller에서 username을 파라미터로 받고 있었습니다. 다른 사용자가 타인의 계정을 입력하면 타인의 정보를 모두 조회할 수 있는 위험한 로직이었습니다.

클라이언트에게 username을 받지 않고, Spring Security가 가지고 있는 사용자의 인증 정보를 가져오도록 변경했습니다.



❓ 인증된 유저의 정보가 저장되는 과정

폼 로그인에 성공한 유저의 정보는 UserDetailService를 구현한 클래스에서 유저 정보 반환 메소드를 가진 UserDetails 객체로 만들어집니다.

그리고, AuthenticationManager에 의해 인증 완료 객체가 생성되어 SecurityContextAuthentication 객체로 저장됩니다.


Authentication 객체에 접근하기 위해서는 아래와 같이 왼쪽에서 오른쪽 순으로 접근할 수 있습니다.

SecurityContextHolder > SecurityContext > Authentication

  • SecurityContextHolder: 보안 주체의 보안 컨텍스트에 대한 세부 정보
  • SecurityContext: Authentication 객체 보관 및 반환
  • Authentication: 현재 접근하는 주체의 정보와 권한



💡 인증된 유저의 정보 반환

  1. SecurityUtil 클래스를 만들어 UserDetails의 정보를 반환하는 메소드 생성
  2. 유저 정보가 필요한 서비스 레이어에서 SecurityUtil 클래스를 주입해 인증된 유저의 정보를 반환 받기



Spring Security 모듈 사용하기

개발 환경

  • Spring Boot 3
  • Java 17
  • Spring Security

해당 포스팅의 실제 코드는 EunsilSon - BookMarky에서 확인할 수 있습니다.


🟢 SecurityUtil

SecurityContextHolder를 import 받고, SecurityContextHolder의 context의 Authentication을 가져옵니다.

authentication.getPrincipal() instanceof UserDetails userDetails
  • 인증된 유저의 주체(principal)의 반환 값이 UserDetails이라면 userDetails라는 변수에 할당
  • instanceof: 객체가 특정 클래스나 인터페이스의 인스턴스인지에 대한 여부 확인

    위와 같은 패턴 매칭 코드는 Java 16 이상 사용 가능




🟢 Service

아래의 코드는 특정 사용자가 저장한 정보를 불러오는 메소드입니다.
username을 파라미터로 받지 않고, SecurityUtil의 메소드를 호출해 반환받고 있습니다.


끝!

post-custom-banner

0개의 댓글