모르지 않다는 것은 아는것과 다르다.

Spring Security

Custom Filter

채마스 2022. 2. 28. 20:49

Custom Filter 구현

  • Spring Security Custom Filter 를 만들 수 있다.
  • 기본적은 서블릿 필터를 만드는 것과 동일하다.
  • 아래와 같이 구현할 수 있다.
public class LoggingFilter extends GenericFilter {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        chain.doFilter(request, response);

        stopWatch.stop();
        logger.info(stopWatch.prettyPrint());
    }
}
  • GenericFilter 를 상속받으면 스프링에 친화적인 필터를 만들 수 있다.
    • OncePerRequestFilter 를 상속받아서 구현하는 경우도 많다.
  • 아래와 같이 어떤 위치에서 실행될 것인지를 설정해 줄 수 있다.
http.addFilterAfter(new LoggingFilter(), UsernamePasswordAuthenticationFilter.class);
  • UsernamePasswordAuthenticationFilter 뒤에 커스텀해서 만든 LoggingFilter 를 위치시킬 수 있다.
  • chain,doFilter(request, response); -> 다음 필터로 넘어기는 코드이다. -> 이 코드를 적어줘야 다음 필터로 넘어간다.
/**
 * 테스트 유저인 경우에는 어드민과 유저 권한 모두를 줍니다.
 */
public class TesterAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    public TesterAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        Authentication authentication = super.attemptAuthentication(request, response);
        User user = (User) authentication.getPrincipal();
        if (user.getUsername().startsWith("tester")) {
            return new UsernamePasswordAuthenticationToken(
                    user,
                    null,
                    Stream.of("ROLE_ADMIN", "ROLE_USER")
                            .map(authority -> (GrantedAuthority) () -> authority)
                            .collect(Collectors.toList())
            );
        }
        return authentication;
    }
}
  • 위와 같이 테스트 유저인 경우 모든 권한을 부여하는 로직을 필터로 구현할 수 있다.
// stopwath filter
http.addFilterAfter(
    new LoggingFilter(), 
    UsernamePasswordAuthenticationFilter.class
);

// tester authentication filter
http.addFilterBefore(
        new TesterAuthenticationFilter(this.authenticationManager()),
        LoggingFilter.class
);
  • 위와 같이 먼저 만든 LoggingFilter 뒤에 위치 시킬 수 있다.
    • 만약 앞에 위치시키고 싶다면? -> http.addFilterAfter 를 사용하면 된다.




REFERENCES

  • 백기선님의 스프링 시큐리티
  • 안성훈님의 스프링 시큐리티

'Spring Security' 카테고리의 다른 글

Custom DSL 적용  (0) 2022.02.28
Ajax 인증처이  (0) 2022.02.28
RememberMeAuthenticationFilter  (0) 2022.02.28
AccessDesicionManager 와 AccessDecisionVoter  (0) 2022.02.28
ExceptionTranslationFilter,RequestCacheAwareFilter  (0) 2022.02.28