Spring Security가 적용된 프로젝트에서 사용자가 API를 호출했을 때 사용자의 정보가 필요한 때가 있다.
한 가지 예로 데이터 수정 시 테이블 updateBy 필드에 들어갈 사용자 ID 같은 것들?
그래서 @AuthenticationPrincipal 어노테이션을 사용해서 사용자 정보 조회하는 것을 알아보게 되었다.
인증 객체
Spring Security를 적용하면 인증 객체(Authentication)을 SecurityContextHolder 내부의 SecurityContext에 저장하고 있다.
그렇기 때문에 컨트롤러에서 @AuthenticationPrincipal을 사용해 인증 객체의 정보를 조회할 수 있는 것이다.
MemberInfo
@Getter
public class MemberInfo extends User {
private String userId;
public MemberInfo(String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
this.userId = username;
}
}
Spring Security의 User를 상속받는 커스텀 클래스를 만들었다. 지금은 userId 필드만 존재하는데, 이후 필요하다면 추가 정보를 추가해서 사용해도 된다.
JwtFilter & TokenProvider
Authentication authentication = tokenProvider.getAuthentication(accessToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
Jwt 필터에서 인증 객체를 조회해서 SecurityContext에 저장하는 부분이다.
토큰에서 인증 객체를 조회하는 메소드를 살펴보도록 하자.
public Authentication getAuthentication(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(this.secretKey)
.build()
.parseClaimsJws(token)
.getBody();
Object authoritiesCliam = claims.get("role");
Collection<? extends GrantedAuthority> authorities = (authoritiesCliam == null) ?
AuthorityUtils.NO_AUTHORITIES : AuthorityUtils.commaSeparatedStringToAuthorityList(claims.get("role").toString());
// User를 상속받는 커스텀 클래스를 생성자 메소드 사용해서 객체 생성
MemberInfo memberInfo = new MemberInfo(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(memberInfo, token, authorities);
}
Jwt 토큰에 저장된 데이터를 활용해 MemberInfo 객체의 필드를 채워서 인증 객체를 반환하게 되고, 이 인증 객체를 ContextHolder에 설정한다.
MemberController
@PutMapping("/{id}")
public ResponseEntity<Object> editMember(
@PathVariable Long id,
@RequestBody MemberEditDto memberEditDto,
@AuthenticationPrincipal MemberInfo memberInfo) {
return ResponseEntity.ok(memberService.editMember(id, memberEditDto, memberInfo));
}
멤버 컨트롤러의 멤버 수정 API이다. 파라미터 중 @AuthenticationPrincipal MemberInfo memberInfo를 받는 부분이 있는데, 간단하게 위의 Jwt 필터에서 설정한 MemberInfo 객체를 가져올 수 있다.
디버깅 시 memberInfo에 토큰에 담긴 userId가 잘 담기는 것을 확인할 수 있다.
끝.
'Spring Boot' 카테고리의 다른 글
[Spring Boot] MapStruct (0) | 2024.04.26 |
---|---|
[Spring Boot] Redis 적용해서 토큰 정보 저장 후 자동 갱신하기 (0) | 2023.12.25 |
[Spring Boot] 로그인 성공 시 쿠키에 accessToken 넣기 (0) | 2023.12.25 |