Error

JWT Token AccessDenied 403 Error

kkkkkdddddhhhhh 2024. 1. 2. 05:03

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 객체를 요상하게 만든 바람에 생긴 이슈...

 

이런 문제를 겪는 유일한 사람일거같은