[Spring Security] @PreAuthorize에서 활용하고 있는 인증 객체 warning 해소

2025. 7. 3. 09:50Spring/Basic

반응형

인증과 관련된 객체를 커스텀한 AuthUser 객체가 있고,

public record AuthUser(
    Long userId,
    String name,
    Long userGroupId,
    UserType userType)
    implements Serializable {
  
  AuthUser(User user) {
    this(
        user.getUserId(),
        user.getName(),
        user.getRoleGroup() == null ? null : user.getRoleGroup().getRoleGroupId(),
        user.getUserType()
        user.getUsername());
  }

  public boolean isAdmin() {
    return UserType.ADMIN == userType;
  }

  public boolean isBasic() {
    return UserType.BASIC == userType;
  }
}

일반적으로는 이 커스텀 인증 객체를 이용하여 요청을 보낸 authUser에 관한 정보를 읽어들여 서비스 클래스의 메서드에서 활용하고 있습니다.

@PreAuthorize("@cardSecurityService.allowAccess(#authUser)")
@Secured(Roles.Card.READ)
@PutMapping("/{cardId}")
public void updateCard(
        @PathVariable String cardId, @Auth AuthUser authUser) {
    cardService.update(cardId, CardRequestMapper.INSTANCE.toCommand(reques, authUser.userId()));
}
@Service
class cardSecurityService {

  public boolean allowAccess(AuthUser user) {
    return user.isAdmin();
  }

}

위와 같이 코드 블럭 내에서 authUser를 사용하고 있는 경우에는 문제가 없겠지만

만일 아래와 같이 @PreAuthorized에서만 해당 객체를 사용하고, 코드 블럭 내에서는 사용하지 않는다면 IntelliJ에서 Parameter 'authUser' is never used 라는 문구와 함께 회색 글자로 표기됩니다.


@PreAuthorize 에서 해당 객체를 활용하지만, 메서드 내에서는 사용되지 않은 상황이라 IntelliJ는 해당 파라미터가 사용되지 않았다고 판단하고 있습니다.


1. IntelliJ의 warning 억제

아주 단순하게 컨트롤러 메서드에 @SuppressWarnings("unused") 설정하여 IntelliJ에 안쓰는 파라미터에 대한 경고를 표시하지 않도록 하여 이 문제를 해소할 수 있습니다.

@SuppressWarnings("unused")
@PreAuthorize("@cardSecurityService.allowAccess(#authUser)")
@Secured(Roles.Card.READ)
@GetMapping("/{cardId}")
public void updateCard(@PathVariable String cardId, @Auth AuthUser authUser) {
  cardService.select(cardId);
}

그러면 아래와 같이 authUser 파라미터가 회색으로 표기되던 것이 해소된 것을 확인할 수 있습니다.


2. 블럭 내부에서 authUser 사용하기

메서드 블럭안에서 어떤식으로든 authUser를 활용하는 방식으로도 warning을 해소할 수도 있습니다.

@PreAuthorize("@cardSecurityService.allowAccess(#authUser)")
@Secured(Roles.Card.READ)
@GetMapping("/{cardId}")
public void updateCard(@PathVariable String cardId, @Auth AuthUser authUser) {
  if(authUser == null) return;
  cardService.select(cardId);
}

3. @PreAuthorize에서 authentication 활용하기

@PreAuthorize 에서는 Spring Security에서 제공하는 Authentication 객체를 바로 사용할 수 있습니다.

@PreAuthorize("@cardSecurityService.allowAccess(authentication)")
@Secured(Roles.Card.READ)
@GetMapping("/{cardId}")
public void updateCard(@PathVariable String cardId) {
  cardService.select(cardId);
}

Authentication으로 대체하고, allowAccess 메서드에서 authentication 객체로부터 AuthUser를 꺼내서 사용할 수 있습니다.

위에서 소개했던 나머지 2가지 방식보다 더 깔끔한 구조이기에 전체 구조를 깔끔하게 설정하고 싶다면 이와 같은 방식을 권장합니다.

@Service
class CardSecurityService {
  
  public boolean allowAccess(Authentication authentication) {
    if (authentication.getPrincipal() != null
        && authentication.getPrincipal() instanceof AuthUser authUser) {
      return authUser.isAdmin();
    }
    return false;
  }

}
728x90
반응형