[Spring Security] Jwt 토큰정보로 필터링 된 유저정보를 컨트롤러단에서 @AuthenticationPricipal 어노테이션을 통해 가져오는법

Jinseok Lee·2020년 2월 5일
7
post-thumbnail
post-custom-banner

사연

  • 스프링 시큐리티에서 Jwt 토큰정보로 필터링 된 SecurityContext 정보를 컨트롤러 단에서 SecurityContext.getContext() 함수를 통해 복잡하게 가져오지 말고 @AuthenticationPrincipal 어노테이션을 통해 직접 불러오고 싶어졌다.
  • 인증방식에서 Session을 사용하면 스프링 시큐리티에서 자동으로 잡아주기 때문에 상관없겠다.

방법

JwtAuthenticationFilter.java

private Authentication getAuthentication(HttpServletRequest request) {

  String token = request.getHeader("Authorization");

  if (token == null) {
    return null;
  }

  Claims claims;

  try {
    claims = jwtUtil.getClaims(token.substring("Bearer ".length()));
  } catch (JwtException e) {
    throw new AuthException.MalformedJwt(token);
  }

  Set<GrantedAuthority> roles = new HashSet<>();
  String role = (String) claims.get("role");
  roles.add(new SimpleGrantedAuthority("ROLE_" + role));

  return new UsernamePasswordAuthenticationToken(new User(claims), null, roles);
}

마지막에 UsernamePasswordAuthenticationTokenAuthentication을 반환해줄때 첫번째 파라미터로 User를 넘긴다.

return new UsernamePasswordAuthenticationToken(new User(claims), null, roles);

User.java

@Entity
@Getter
@NamedQuery(name = "findByEmail", query = "select u from User u where u.email = :email")
@NoArgsConstructor
public class User  {

    @Id @GeneratedValue
    private Long id;

    @Column(name = "password")
    private String password;

    @Column(name = "email")
    private String email;

    @Column(name = "name")
    private String name;

    @Transient
    private String role;

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    public User(Claims claims) {
        this.id = Long.valueOf(claims.get("userId").toString());
        this.name = claims.get("name").toString();
        this.role = claims.get("role").toString();
    }

    public User(RegisterRequestDto registerRequestDto) {
        this.password = registerRequestDto.getPassword();
        this.email = registerRequestDto.getEmail();
        this.name = registerRequestDto.getName();
    }

}

Controller.java

@ResponseStatus(HttpStatus.OK)
@GetMapping
public List<ArticleResponseDto> getArticles(Pageable pageable, @AuthenticationPrincipal User user) {
  return articleService.findAll(pageable, user);
}

@AuthenticationPrincipal 어노테이션을 통해 정상적으로 필터링된 사용자 정보가 들어오는 것을 확인할 수 있었다.

@AuthenticationPrincipal User user

여기에서 User는 작성하는 자의 판단에 따라 어떤 이름이든 형식이든 올 수 있다. 다만 UsernamePasswordAuthenticationToken의 첫번째 파라미터와 일치시켜주는 것이 포인트!

전체 소스코드

profile
전 위메프, 이직준비중
post-custom-banner

0개의 댓글