인증/인가 구현이 머릿속에 정리되지 않아 스스로 설계할 수 있을 정도가 될 때까지 공부 중
JWT로 클라이언트 인증/인가를 처리하는 작업을 하고 있다.
클라이언트에게 웹 서비스를 제공할 때, 인가된 사용자에게 서비스를 제공해야하는 경우가 있을 것이다.
인증/인가를 적용하기 전에는 API 요청하면 바로 그에 맞는 서비스를 응답하였지만,
클라이언트가 서비스 API를 요청하면 그 전에 인증/인가를 진행하고 나서 OK가 되면 그에 맞는 서비스가 제공되어야 한다.
서비스 사용자 입장에서는 인증이 필요한 서비스를 이용하려 할 때,
우선적으로 인증처리를 해주고 (보통 로그인), 성공하면 그 후부터 많은 서비스에 접근가능해진다.
우리가 웹 통신으로 클라이언트와 정보를 주고받는 방법은 HTTP인데
요놈은 비연결, 무상태(stateless) 특징 때문에 클라이언트가 접근권한이 필요한 서비스를 클릭(요청)할 때마다 서버입장에서는 매번 인가처리를 해주어야 한다. (아까 로그인 성공한 너 맞음?)
이 때 Filter를 사용하면 좋다.
해결책은 Filter 뿐이 아니라 Interceptor, AOP 또한 있다.
매번 인가처리를 하는 방법이 반드시 Filter를 사용해야 하는 것은 아니지만
Filter를 사용하지 않는다면 인가를 요구할 때마다
인가처리하는 API를 먼저 실행 후 인가가 나면 서비스 API를 다시 요청하는 방식 등
어쨌든 컨트롤러 & 서비스 로직 단에서 매번 같은 일을 하게 되어 비효율적일 것으로 보인다.
Filter는 서블릿 이전에 실행된다고 배웠다.
그래서 Filter 클래스를 구현하고 나면 3계층 아키텍쳐 로직에서는 인증/인가에 대해 신경쓸 필요가 적어진다.
주로 사용하려는 용도는 클라이언트 인증/인가, 로깅, 인코딩 변환, XSS방어, CORS 등이 있다고 한다. XSS와 CORS는 무엇인지 정확히는 모르겠으니 다음에 공부하기로 한다.
(서블릿 필터. Security 아님)
@Component
public class JwtFilter implements Filter {}
참고사항: 검색되는 Filter 클래스가 많아서 아래 패키지를 임포트해야 함을 주의
import jakarta.servlet.Filter;
Filter 인터페이스를 구현하여 작성
filterChain.doFilter(servletRequest, servletResponse); 를 실행하면 필터를 넘어가 본 서비스 로직으로 가게 됨. 또는 다중 필터일 경우 다음 필터로 넘어감. 다시 말하면, 인가 실패 로직은 filterChain 실행하지 않고 메서드 종료.Filter 구현 클래스를 언제 어떻게 필터링할 것인지 설정 클래스 작성
@Configuration
@RequiredArgsConstructor
public class JwtFilterConfig {
// 필터 구현 클래스
private final JwtFilter jwtFilter;
@Bean
public FilterRegistrationBean<JwtFilter> jwtFilterRegistrationBean() {
// FilterRegistrationBean 객체 생성
FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();
// 필터 구현 클래스 세팅
registrationBean.setFilter(jwtFilter);
// 필터 체인 순서
registrationBean.setOrder(1);
// 필터링 적용할 API URL 패턴
registrationBean.addUrlPatterns("/schedules/*");
return registrationBean;
}
}
필터링을 적용하기 위해 URL 패턴을 설정하는 addUrlPatterns("/") 메서드 사용에서 겪은 문제
예를들어, API path가 /schedules/{scheduleId}/comments/{commentId} 인 것들을 필터링하려고 했는데
필터링을 제외하는 path 중에 /schedules/{id}가 있어서
addUrlPatterns("/schedules/*/comments/*") 로 적용하였지만 필터가 작동하지 않았다. addUrlPatterns("/schedules/*")는 필터가 정상 작동하므로 다른 문제는 아닌듯 하다.
패턴 문제라고 생각하여 와일드카드 표현 형식이 다른지 찾아봤지만 수확이 없었다.
남는 것은 공식 문서를 정독해보는 것일 뿐..!
현재 도출한 결론은 와일드카드를 저렇게 중간에 넣고 마지막에도 또 다시 들어가는 패턴은 작동이 되지 않는 듯 하다. (에러는 나지 않는다.)
내가 한 해결방법은 API를 RESTful 하게 리팩토링해서 와일드카드를 하나만 써도 되도록 바꾸는 것이다.