사전 개념
JWT 토큰
Filter
JWT 토큰을 통한 Gateway 인증 및 권한 관리 동작 확인
동작 과정 아키텍처
목표
- 사용자가 API Gateway(91번 서버)를 통해 /auth/sign?user_id 엔드포인트로 요청을 보냅니다.
- user_id를 기반으로 JWT 토큰이 생성되어 응답으로 반환됩니다.
- 사용자는 이 JWT 토큰을 이용하여 product 엔드포인트를 호출합니다.
- API Gateway(91번 서버)에서 JWT 토큰을 필터(Filter)를 통해 검증하여 로그인된 사용자인지 확인합니다.
- 토큰 검증이 통과하면, product 요청이 93번 서버의 product 서비스로 전달됩니다.
구성 요소
Gateway Applicatio
위 코드는 Spring Cloud Gateway에서 JWT Secret Key를 사용하여 인증을 처리하는 GlobalFilter를 구현한 것입니다.
이 필터는 요청의 Authorization 헤더에 포함된 JWT 토큰을 검증하여 요청이 유효한지 확인합니다.
요청이 인증되지 않은 경우, 필터는 UNAUTHORIZED 상태 코드를 반환하여 접근을 차단합니다.
이를 통해 인증된 사용자만 접근할 수 있는 경로를 보호할 수 있습니다.
- @Value("${service.jwt.secret-key}")
- JWT 서명 검증에 사용할 비밀 키를 application.yml 파일에서 가져옵니다.
- filter() 메서드
- 요청 URI가 /auth/signIn일 경우
필터를 적용하지 않고 요청을 다음 단계로 전달합니다. - extractToken 메서드()를 호출하여 Authorization 헤더에서 JWT 토큰을 추출합니다.
- validateToken 메서드()를 호출하여 추출된 JWT 토큰의 유효성을 검증합니다.
- 검증 실패 시 401 Unauthorized 상태 코드로 응답하고 요청을 종료합니다.
- 요청 URI가 /auth/signIn일 경우
- extractToken() 메서드
- Authorization 헤더에서 JWT 토큰을 추출합니다.
- 토큰은 Bearer 로 시작하므로, 이 접두사를 제거하고 실제 토큰(순수 토큰)만 반환합니다.
- validateToken() 메서드
- 비밀 키를 사용하여 JWT 토큰의 서명을 검증합니다.
- 서명이 유효하면 페이로드를 로그에 기록하고, 토큰이 유효하다고 판단합니다.
- 91번 서버 (API Gateway)
- 사용자의 요청을 받아서 인증 및 토큰 검증을 수행하며, 인증된 요청만 product 서비스로 전달합니다.
Product Application
- 93번 서버 (Product 서버)
- 실제 제품 서비스를 제공하는 서버입니다.
Auth Application
- 19095번 서버 (인증 및 로그인 서버)
- user_id를 기반으로 JWT 토큰을 생성하고 사용자 인증을 처리하는 서버입니다.
먼저 Eureka 서버를 실행시키고 "localhost:19090"에 접속을 해보면 위와 같이 AUTH-SERVICE가 잘 연결된 것을 확인할 수 있습니다.
"http://localhost:19095/auth/signIn?user_id=aaa"로 접속해보면 토큰값이 정상적으로 나온 것을 확인할 수 있습니다.
발급받은 토큰을 jwt.io에 들어가서 넣어서 payload를 확인해보면 user_id와 role이 aaa,ADMIN으로 정상적으로 나옵니다.
"19095/auth/signIn?user_id=aaa"로 접속했을 때 POSTMAN이나 Talend를 통해서도 확인을 해보면 위와같이 정상적으로 토큰을 확인할 수 있습니다.
그럼이제 토큰을 발급 받았으니깐 로그인된 사용자 정보를 가지고 product를 호출해보겠습니다.
이 과정에서 확인할 점은 API Gateway(포트 19091)를 통해 Sign In 요청을 정상적으로 처리할 수 있는지입니다.
즉, API Gateway를 통해 로그인 요청이 제대로 작동하는지 확인해보겠습니다.
19091/auth/signIn?user_id=aaa 경로로 API Gateway(포트 19091)를 통해 접속하면, 요청이 정상적으로 auth 서버로 전달되어 로그인이 성공적으로 이루어지는 것을 확인할 수 있습니다.
현재 인증(Auth) 처리는 API Gateway에서만 이루어지고 있으며, 93번 서버는 별도의 인증 처리를 하지 않고 있습니다. 따라서 위와 같이 93번 서버에 직접 접속할 경우, 인증 없이 정상적으로 접근할 수 있습니다.
이제 API Gateway(91번 서버)를 통해 product 서비스를 호출해 보겠습니다.
로그인 요청으로 발급받은 JWT 토큰을 Authorization 헤더에 포함시켜 http://localhost:19091/product 엔드포인트를 호출합니다.
이 호출은 API Gateway를 통해 전달되며, product 서비스(포트 93번)로 요청이 정상적으로 호출되는 것을 확인할 수 있습니다.
SessionCreationPolicy
SessionCreationPolicy는 Spring Security에서 세션의 생성 및 관리 방식을 제어하는 설정입니다.
이 설정은 Spring Security의 웹 보안 구성에서 주로 사용되며, 클라이언트와 서버 간의 세션 관리 방식을 정의합니다.
SessionCreationPolicy의 옵션에 대한 한 줄 설명은 다음과 같습니다:
- ALWAYS
- 요청이 들어올 때마다 항상 새로운 세션을 생성합니다.
- IF_REQUIRED
- 세션이 필요한 경우에만 세션을 생성합니다. 기본값입니다.
- NEVER
- 세션을
절대 생성하지 않습니다.
- 세션을
- STATELESS
-
세션을 사용하지 않고,요청 간 상태를 유지하지 않습니다.
-
따라서 이번 "JWT 토큰을 통한 Gateway 인증 및 권한 관리 동작 확인"에서는 JWT토큰을 사용할 것이기 때문에 세션을 사용하지 않도록 STATELESS 설정을 했습니다.