AbstractAuthenticationProcessingFilter 구현 메서드에 관한 질문 #17
-
JwtAuthenticationFilter에서 Override한 위 메서드들에 대해서 궁금한게 있습니다! 1. requiresAuthentication를 override 한 이유AbstractAuthenticationProcessingFilter의 requiresAuthentication method는 아래와 같습니다.
Override해서 구현한 return matcher.matches(request);의 기능이 AbstractAuthenticationProcessingFilter에서 이미 구현되어 있는 것 같은데, 새롭게 구현해서 사용하는 이유가 궁금합니다! 2. successfulAuthentication, unsuccessfulAuthentication를 override한 이유AbstractAuthenticationProcessingFilter의 successfulAuthentication method는 아래와 같습니다.
현재 선필님이 작성하신 코드에서는
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
질문과 약간은 관련이 없지만 successfulAuthentication 을 오버라이딩 하는 이유중에 하나는, 기본적으로 오버라이딩을 하지 않을 경우 AbstractAuthenticationProcessingFilter 에 구현된 super.successfulAuthentication() 을 호출하게 되는데 해당 메소드에서는 내부적으로 이전 인증 실패에 대한 요청인 savedRequest 를 가져와서 처리하게 되는걸로 알고있습니다. 선필님이 작성하신 코드를 직접 실행해보진 않았지만 제가 개인적으로 프로젝트를 진행했을 때의 이슈로 JWT 인증시 이런 이유로 실패하는 케이스가 있었는데요. 저 같은 경우는 Spring Security 에서 제공해주는 로그인 폼을 사용하지 않고 별도의 /auth/login API 를 통해서 로그인처리를 했고, Spring Security 를 이용해서는 단순히 JWT 토큰 인증에 대한 처리만 했었습니다. JWT 토큰 인증에 성공해서 super.successfulAuthentication() 이 호출되었을 때 이전에 인증에 실패한 요청이 당연히 없기 때문에 savedRequest 는 null 이고 이에 따라 기본값으로 설정된 경로인 "/" 로 리다이렉트를 시키게 되었고 "/" 로 요청을 보내는 와중에 또 JWT 토큰 검증을 위한 Spring Seucrity Filter 를 만나게 되고.... 무한 반복 이었던 이슈였습니다. 그래서 저는 기본적으로 구현된 super.successfulAuthentication() 말고 아래 핸들러를 직접 구현해서 사용했었습니다..!
아니면 "/" 경로에 대해서 해당 필터를 예외처리해도 해결이 가능했습니다. 선필님 코드랑은 다른 케이스지만 이것때문에 예전에 고생한 기억이 떠올라 공유드려봅니다 ㅎㅎㅎ |
Beta Was this translation helpful? Give feedback.
-
1. requiresAuthentication를 override 한 이유먼저 의도를 설명드리자면, 다른 이유가 있다기 보다는 단순히 커스텀 matcher를 사용해서 인증 필터를 건너뛸 paths를 비교하는 메소드가 그리고 동균님께서 지적해 주신 김에 코드를 다시 살펴봤는데, 리팩토링을 고려할 만한 부분을 찾은 것 같아서 두 분의 의견을 한 번 여쭤보고 싶습니다..! 우선, 생성자 // AbstractAuthenticationProcessingFilter.java
protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
Assert.notNull(requiresAuthenticationRequestMatcher, "requiresAuthenticationRequestMatcher cannot be null");
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
} 위의 부모 생성자를 호출하도록 변경해보면, public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private final JwtUtils jwtUtils;
- private final RequestMatcher matcher;
public JwtAuthenticationFilter(RequestMatcher matcher, JwtUtils jwtUtils) {
- super(ALL_PATTERN);
+ super(matcher);
this.jwtUtils = jwtUtils;
- this.matcher = matcher;
}
- @Override
- protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
- return matcher.matches(request);
- } 다만, 아쉬운 점은 위의 방식처럼 수정을 하는 것과, 혹은 기존 코드에서 아래와 같이 수정하는 방식 중 어떤 게 더 나을까요?🤔 public class SkipPathRequestMatcher implements RequestMatcher {
...
@Override
public boolean matches(HttpServletRequest request) {
- return !matcher.matches(request);
+ return matcher.matches(request);
}
} public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
...
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
- return matcher.matches(request);
+ return !matcher.matches(request);
} 2. successfulAuthentication, unsuccessfulAuthentication를 override한 이유
---(수정)--- public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
...
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authResult);
- super.successfulAuthentication(request, response, chain, authResult);
+ super.successHandler.onAuthenticationSuccess(request, response, chain, authResult);
}
} |
Beta Was this translation helpful? Give feedback.
1. requiresAuthentication를 override 한 이유
먼저 의도를 설명드리자면, 다른 이유가 있다기 보다는 단순히 커스텀 matcher를 사용해서 인증 필터를 건너뛸 paths를 비교하는 메소드가
requiresAuthentication()
이라서 재정의하려는 생각으로 구현 했던 것 같습니다.그리고 동균님께서 지적해 주신 김에 코드를 다시 살펴봤는데, 리팩토링을 고려할 만한 부분을 찾은 것 같아서 두 분의 의견을 한 번 여쭤보고 싶습니다..!
우선, 생성자
JwtAuthenticationFilter()
에서 다른 부모 생성자를 호출하게 되면requiresAuthentication()
메소드를 굳이 재정의 할 필요가 없어질 것 같습니다.