//Controller
@GetMapping
public ResponseEntity<Page<FishBreadListResDto>> findFishBreadAll(Pageable pageable,
@ModelAttribute SearchCondition searchCondition,
@AuthenticationPrincipal UserPrincipal principal) {
return ResponseEntity.ok(fishBreadService.findBySearchCondition(principal.getUserId(), pageable, searchCondition));
}
현재 나는 @AuthenticationPrincipal을 사용해서 유저의 정보를 가져온다.
만약, 유저가 로그인 하지 않은 유저라면 principal의 값에 null이 들어온다.
예를들어 물론 로그인안됨에러라는 Custom한 예외를 뿌려줘도 되기도 하고,
if(principal == null) {
throw new 로그인안됨에러();
}
@Secured({"ROLE_USER","ROLE_ADMIN"})
을 Controller쪽 @GetMapping 옆에다가 둬도 되겠지만, 현재 에러 객체를 통일시켜서 반환하기 때문에 가능하면 내가 제어할 수 있는 범위에서는 에러 규격을 맞추고 싶었다.
검색을 하는데 @AuthenticationPrincipal이 null이 나온다는 에러만 많고 에러를 던지는 문서는 거의 없는 것 같다.
그러던 중에 커스텀 어노테이션을 만들고 그것을 HandlerMethodArgumentResolver을 상속받는 Class를 만들어서 처리하는 방법을 찾았고
참조한 문서는 이거다
꼭 봐서 대충이라도 이해했으면 좋겠다.
왜냐면 난 설명하지 않을거니까!
일단, 커스텀 어노테이션을 만들자!!
나는 AuthUser라는 어노테이션을 사용하여 인증된 사용자만 받을 것이다!
다음은 HandlerMethodArgumentResolver 를 만들자
저 문서를 보면 알겠지만 HandlerMethodArgumentResolver는 일단 너무너무너무너무 많은 클래스들의 부모 인터페이스다.
뭐가 있는지 아는건 중요하지 않고 이 메서드가 뭘 하는 애인가를 알아야한다.
boolean supportsParameter(MethodParameter parameter);
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
이 두가지 메서드가 정의된 아주 깔끔한 인터페이스다.
supportsParameter는 MethodParameter를 통해서 이걸 지원하냐 안하냐 유무를 따지는거고
만약에 지원한다면 resolveArgument가 실행된다.
이제 HandlerMethodArgumentResolver 를 상속받는 클래스를 작성해보자.
난 CustomAuthArgumentResolver라고 이름 지음
먼저 이걸 적용시키기 위해서 supportsParameter 를 간다.
"이거 파라미터로 온 거의 어노테이션이 AuthUser야?" 라고 묻는다. 물론 아니라면 null이 될 것이다.
중요한건 null이 아니면 파라미터로 온 클래스 타입이 UserPrincipal 클래스와 일치하는지 여부를 return 시키고
일치한다면 resolveArgument로 넘어간다.
넘어 간 후 SecurityContextHolder에 저장된 인증 객체를 가져 온 후 인증 객체가 있다면 해당 값을 반환하지만
없다면 Custom으로 만든 에러를 보낸다. - 대충 인증되지 않은 사용자라는 뜻
자 그럼 만든걸 Spring boot에 적용시켜야 한다.
검색하다보니까 Deprecated 된 WebMvcConfigurerAdapter에도 addArgumentResolvers를 추가할 수 있었다.
하지만 난 WebMvcConfigurerAdapter가 아니라 FilterChain 방식으로 해서 오버라이드를 할 수가 없었는데
다행히 HandlerMethodArgumentResolver 는 WebMvcConfigurer ( 영어 너무 길어....!) 안에 있다.
위와 같이 Bean으로 등록해준 후 addArgumentResolvers에 추가시켜주면 끝이다.!
위처럼 @AuthUser를 추가로 달아주고 실행해보자.
내가 원하는 모양대로 잘 나왔다!!
혹시라도 더 좋은 방법이 있으면 꼭 알려주시기 바랍니다.