Spring Security 폼 로그인을 통해 사용자 인증을 수행했습니다.
로그인에 성공한 사용자의 정보는 Spring Security에 의해 별도의 저장소에 보관됩니다.
그러나, Spring Security가 사용자의 정보를 가지고 있음에도 불구하고, Controller에서 username을 파라미터로 받고 있었습니다. 다른 사용자가 타인의 계정을 입력하면 타인의 정보를 모두 조회할 수 있는 위험한 로직이었습니다.
클라이언트에게 username을 받지 않고, Spring Security가 가지고 있는 사용자의 인증 정보를 가져오도록 변경했습니다.
폼 로그인에 성공한 유저의 정보는 UserDetailService를 구현한 클래스
에서 유저 정보 반환 메소드를 가진 UserDetails 객체
로 만들어집니다.
그리고, AuthenticationManager
에 의해 인증 완료 객체가 생성되어 SecurityContext
에 Authentication 객체
로 저장됩니다.
Authentication 객체
에 접근하기 위해서는 아래와 같이 왼쪽에서 오른쪽 순으로 접근할 수 있습니다.
SecurityContextHolder > SecurityContext > Authentication
- SecurityContextHolder: 보안 주체의 보안 컨텍스트에 대한 세부 정보
- SecurityContext: Authentication 객체 보관 및 반환
- Authentication: 현재 접근하는 주체의 정보와 권한
해당 포스팅의 실제 코드는 EunsilSon - BookMarky에서 확인할 수 있습니다.
SecurityContextHolder를 import 받고, SecurityContextHolder의 context의 Authentication을 가져옵니다.
authentication.getPrincipal() instanceof UserDetails userDetails
instanceof
: 객체가 특정 클래스나 인터페이스의 인스턴스인지에 대한 여부 확인위와 같은 패턴 매칭 코드는 Java 16 이상 사용 가능
아래의 코드는 특정 사용자가 저장한 정보를 불러오는 메소드입니다.
username을 파라미터로 받지 않고, SecurityUtil의 메소드를 호출해 반환받고 있습니다.
자동으로
세션 ID
를 주고 받으며 사용자를 구분하게 됩니다.
[브라우저의 Response Header]
[브라우저의 Request Header]
Response Header와 Request Header의 쿠키가 동일한 것을 확인할 수 있습니다.