Jwt 토큰 인증이 테스트코드에서는 성공적으로 잘 돌아갔다.
최종적으로 POST MAN으로 외부에서 실제로 API요청시에도 정상 기능을 하는지 확인해보기로했는데....
Http 403 code와 함께 권한 인증 오류가 발생했다...
이유가 뭘까 분명히 JWT 코드에는 문제가 없었는데
우선 스프링 시큐리티 debug 를 활성화 시켜 어느 필터에서 문제가 발생했는지 체크해보기로 함.
AuthorizationFilter 에서 AccessDenied 오류가 발생...
AuthorizationFilter에서 권한부여가 실패해 인증실패가 됬다.
처음엔 MethodSecurity를 선언한 Config 문제인줄 알았지만
@Secured도 @PreAutrhorized에 문제도 아닌 상황
디버그 로그를 곰곰히 확인하다 원인을 발견했다.
Security Context에 담긴 인증객체의 권한의 스트링값이 조금 이상하다
[ROLE_ADMIN] 이 아니라 [[ROLE_ADMIN]] 인것....
대괄호로 한번더 씌여져 있기때문에
AuthorizationFilter 에서 충족하는 권한은 [ROLE_ADMIN] 이지만
"[ROLE_ADMIN] " == "[[ROLE_ADMIN]] = false 이기에 권한 인증 실패가 됬던것이다...
그럼 대체 어디서 이 대괄호가 한번더 덮어씌여진것일까??
원인은
액세스 토큰으로 인증객체를 만드는 JwtTokenProvicer.getAuthentication() 메서드에 있었다.
UserDetails를 만들기위해 토큰 클레임에서 사용자의 권한 혹 역할을 가져오는데 사용자 권한의 String값이 "[ROLE_ADMIN]" 으로 return되는것이 확인됬다.
저 Stirng값이 그대로 new SimpleGratedAuthority() 매개변수로 전달되다보니 한번 더 괄호가 씌여지게된것.
정리해보자면,
최초 로그인시 Authentication 객체를 만들기위해 UserPrincipal을 생성하는 과정에서
DB에 "ADMIN" 으로만 존재하던 값을 가져와
ROLE_ 을 prefix해줌과 동시에 "[ ]" 대괄호 역시 SimpleGrantedAuthority 내부적으로 같이 생성해줬던것
이렇게 Token Claims엔 "[ROLE_ADMIN]" 이라는 값이 생성됬고,
로그인 후 인증 요청으로인해 AccessToken Claims에서 사용자 역할이 담긴 "auth"를 get했을때, 그 String Value가 그대로
"[ROLE_ADMIN]" 으로 나왔고
그 String 값으로 또 SimpleGrantedAuthority 에 값을 넣으니
대괄호가 한번 더 씌여져 권한이 일치하지 않았던것.
우선 당장 해결하기위해 AccessToken 기반으로 Authentication 객체를 생성할 때
replaceAll() 을 사용해 대괄호를 지워주고 값을 넘겨줬다.
대괄호가 벗겨진 ROLE_ADMIN을 SimpleGrantedAuthority에 다시 넘겨줬더니
JWT 인증에 성공 할 수 있었다..
현재 replace를 이용해 대괄호를 삭제하는 방식은 임시방편으로 SimpleGrantedAuthority를 커스텀해 로직을 다시 작성할지 고민중이다.
결론은 내가 authentication 객체를 요상하게 만든 바람에 생긴 이슈...
이런 문제를 겪는 유일한 사람일거같은
'Error' 카테고리의 다른 글
RestDocs @AuthenticationPrinciapl 인증 실패 Error (0) | 2024.01.16 |
---|---|
Test were not recieved (0) | 2024.01.09 |
QueryDSL No Property Error (0) | 2023.12.12 |
테스트 환경에서 Cookie를 다루거나 검증해야할때 (0) | 2023.12.08 |
스프링 이미지 출력 문제 (0) | 2023.10.06 |