백엔드 개발 · 심화
Spring Security를 사용하여 OAuth 2.0/OIDC 기반의 인증/인가 시스템을 구축할 때, 토큰 발급 및 검증 과정에서 JWT를 활용하는 경우의 장점과 보안 고려사항(예: 토큰 탈취, 리플레이 어택 방지)은 무엇이며, 이를 Spring Security에서 어떻게 구현할 수 있는지 구체적으로 설명해 주세요.
힌트 · JWT의 무상태성, 서명/암호화, Access Token/Refresh Token 전략, 그리고 Spring Security의 필터 체인 및 커스텀 AuthenticationProvider를 활용한 구현 방안을 언급하세요.
JWTJWS/JWEOAuth 2.0/OIDCSpring Security토큰 탈취/리플레이 공격 방지
모범답안
Spring Security에서 JWT를 OAuth 2.0/OIDC 인증/인가에 활용하는 것은 여러 장점을 가집니다.
JWT의 가장 큰 장점은 무상태성입니다. 서버는 사용자 정보를 세션에 저장할 필요 없이 JWT 자체만으로 인증 및 인가 정보를 확인할 수 있어 확장성이 뛰어납니다. 또한, JWT는 서명(JWS) 또는 **암호화(JWE)**를 통해 무결성과 기밀성을 보장할 수 있습니다.
보안 측면에서는 몇 가지 고려사항이 있습니다.
- 토큰 탈취: JWT가 탈취되면 공격자가 해당 토큰으로 사용자 행세를 할 수 있습니다. 이를 방지하기 위해 토큰에 민감한 정보를 담지 않고, 짧은 만료 시간을 설정하며, HTTPS를 통해 통신해야 합니다. 또한, Refresh Token 전략을 사용하여 Access Token의 만료 시간을 짧게 유지하고, Refresh Token은 안전한 저장소에 보관하여 Access Token 재발급에 사용합니다.
- 리플레이 공격: 탈취된 토큰이 재사용되는 리플레이 공격을 막기 위해, JWT에
exp(만료 시간) 클레임을 반드시 포함하고, 서버에서는 이 만료 시간을 검증해야 합니다. 더 나아가,jti(JWT ID) 클레임을 사용하여 고유 식별자를 부여하고, 서버에서 발급된 토큰 ID를 추적하여 중복 사용을 방지할 수도 있습니다.
Spring Security에서는 이러한 JWT 기반 인증/인가를 필터 체인 내에서 구현합니다.
- JWT 발급: OAuth 2.0/OIDC 인증 플로우가 성공하면, Spring Security는 사용자 정보를 기반으로 JWT를 생성합니다. 이때
Secret Key를 사용하여 서명하고, 필요한 클레임(예:sub,roles,exp)을 포함시킵니다. - JWT 검증: 클라이언트로부터 요청이 오면, Spring Security의
OncePerRequestFilter와 같은 커스텀 필터가 요청 헤더에서 JWT를 추출합니다. 추출된 JWT는Secret Key로 서명을 검증하고, 만료 시간(exp)을 확인합니다. - Authentication 객체 생성: 검증이 성공하면, JWT의 클레임 정보를 바탕으로
UsernamePasswordAuthenticationToken과 같은Authentication객체를 생성합니다. 이 객체에는 사용자 정보와 권한이 포함됩니다. - SecurityContextHolder: 생성된
Authentication객체는SecurityContextHolder에 저장되어, 이후 요청 처리 과정에서 인증 및 인가 정보를 활용할 수 있게 됩니다.
이 과정에서 JwtDecoder와 JwtValidator를 설정하여 JWT의 유효성을 체계적으로 검증하며, CustomAuthenticationProvider를 통해 검증된 JWT 정보를 Authentication 객체로 변환하는 로직을 구현할 수 있습니다. Refresh Token 관리를 위해서는 별도의 TokenService를 구현하여 안전한 발급 및 검증 로직을 추가합니다.
읽었다면, 이제 직접 답해볼 차례예요
패스잇 앱에서 이 질문에 말로 답하면 AI가 꼬리질문까지 이어가며 1:1 코칭합니다.