[Spring] CSRF 제대로 알기
·
Framework/Spring
안녕하세요.이 시리즈는 5편의 Stateless 구성에서 csrf.disable()을 쓰고 지나갔고, 6편에서는 "쿠키를 도입하는 순간 그 전제가 일부 깨진다"고 예고만 해뒀습니다.이번 글은 그 미뤄둔 주제 CSRF(Cross-Site Request Forgery)를 다룹니다.목표는 두 가지입니다."언제 꺼도 되고 언제 켜야 하는가"의 판단 기준을 세우는 것.6편의 쿠키 기반 Refresh 재발급 엔드포인트를 실제로 지키는 것.이번에도 설정 암기보다 "공격이 성립하는 조건이 무엇이고, 방어가 흐름 어디에 끼어드는가" 에 초점을 맞춥니다. 공격 원리 — 브라우저는 쿠키를 자동으로 싣는다CSRF의 성립 조건은 단 하나로 요약됩니다. 인증 수단이 브라우저에 의해 자동 전송된다. 시나리오를 봅니다.사용자가 은..
[Spring] Spring Security 6.x 마이그레이션
·
Framework/Spring
안녕하세요.이 시리즈는 줄곧 Spring Boot 2.7.6(Security 5.7.x)을 기준으로 삼으면서, 곳곳에 "5.8+에서 도입", "6.0에서 제거"라는 각주를 달아왔습니다.이번 글은 그 각주들을 한꺼번에 회수하는 시리즈의 대단원 6.x 마이그레이션입니다.Boot 2.7의 OSS 지원은 이미 종료되었고, 5.7이 "과도기"였다는 것은 곧 이 전환이 선택이 아니라 일정의 문제라는 뜻입니다.이번에도 변경 목록 암기보다 "무엇이 컴파일 오류로 드러나고, 무엇이 조용히 동작만 바뀌는가" 에 초점을 맞춥니다. 위험한 것은 후자입니다. 전제 — 보안만 따로 올릴 수 없다먼저 범위를 정확히 해야 합니다. Security 6.x는 단독 업그레이드가 아니라 플랫폼 전체의 이동입니다.항목현재 (본 시리즈)목표..
[Spring] Spring Security 테스트
·
Framework/Spring
안녕하세요.앞선 글들에서 JWT 인증, 인가, 예외 처리, Refresh Token, CORS까지 REST API 보안 구성을 완성했습니다.이번 글은 그 구성을 테스트로 검증하는 방법입니다.보안 테스트가 어려운 이유는 기능 코드가 아니라 필터 체인과 프록시라는 "위치"에 로직이 숨어 있기 때문입니다.시리즈 내내 다룬 위치 구조를 모르면, 테스트가 프로덕션과 다른 보안 구성으로 돌아가는 것을 눈치채지 못합니다.이번에도 도구 나열보다 "테스트가 어느 계층을 통과하고, 어디를 우회하는가" 에 초점을 맞춥니다. 준비 — spring-security-test org.springframework.security spring-security-test test이 의존성이 제공하는 도구는 크게 세 계열..
[Spring] Spring Security와 CORS
·
Framework/Spring
안녕하세요.앞선 여섯 글에서 Spring Security의 구조, 인증, 인가, 예외 처리, JWT 구현, Refresh Token까지 정리했습니다.이렇게 만든 REST API를 프런트 분리 환경(SPA)에 실전 투입하면 거의 예외 없이 처음 마주치는 벽이 있습니다."Postman에서는 되는데 브라우저에서는 안 된다." 이번 글은 그 벽인 CORS(Cross-Origin Resource Sharing)를 다룹니다.이번에도 설정 암기보다 "CORS 처리가 요청 흐름 어디에 끼어드는가" 에 초점을 맞춥니다.1편의 필터 위치 관점이 그대로 재등장합니다. CORS는 서버가 아니라 브라우저의 정책이다가장 먼저 바로잡아야 할 오해입니다. CORS 오류는 서버가 요청을 거부한 것이 아닙니다.동일 출처 정책(Same..
[Spring] Spring Security Refresh Token과 토큰 무효화
·
Framework/Spring
안녕하세요.앞선 다섯 글에서 Spring Security의 전체 구조(FilterChain), 인증, 인가, 예외 처리, 그리고 JWT 기반 Stateless 인증 구현까지 정리했습니다.5편의 마지막에 남겨둔 숙제가 있었습니다."발급한 토큰을 회수할 수 없다." 이번 글은 그 숙제를 푸는 Refresh Token 도입과 로그아웃/강제 만료 전략, 그리고 그 순간 다시 생겨나는 "상태"를 어디에 둘 것인가의 트레이드오프를 다룹니다.이번에도 코드 복사보다 "어느 시점에 무엇을 검증하고, 상태가 어디에 생기는가" 에 초점을 맞춥니다. 왜 Refresh Token인가5편에서 확인한 Stateless의 구조적 약점은 두 가지였습니다.약점원인탈취된 토큰을 막을 수 없다서명만 유효하면 만료까지 통과로그아웃이 서버에..
[Spring] Spring Security JWT 인증 구현
·
Framework/Spring
안녕하세요.앞선 네 글에서 Spring Security의 전체 구조(FilterChain), 인증(Authentication), 인가(Authorization), 예외 처리를 정리했습니다.이번 글은 JWT 기반 Stateless 인증을 직접 구현하면서 커스텀 인증 필터 작성과 "앞쪽 필터 예외가 EntryPoint를 우회하는 함정" 대응을 코드와 함께 다루는 실전편입니다.이번에도 코드 복사보다 "각 코드가 필터 체인의 어느 위치에서 무엇을 하는가" 에 초점을 맞춥니다.위치를 모르면 복사한 코드가 왜 동작하는지(혹은 왜 안 하는지) 설명할 수 없기 때문입니다. 왜 Stateless인가2편 마지막에 정리했던 인증 상태 유지 방식을 다시 떠올려 보면, 세션 방식과 토큰 방식의 차이는 "인증 상태를 누가 들고..
[Spring] Spring Security 예외 처리
·
Framework/Spring
안녕하세요.앞선 세 글에서 Spring Security의 전체 구조(FilterChain), 인증(Authentication), 인가(Authorization)를 정리했습니다.이번 주제는 인증 실패(401)와 인가 실패(403)를 어떻게 일관된 JSON 응답으로 번역하는가 입니다.이번에도 설정 암기보다 "예외가 어디서 잡혀서 어디로 흐르는가" 에 집중합니다.흐름을 모르면 "왜 내 @RestControllerAdvice가 안 타지?" 에서 멈추기 때문입니다. 두 종류의 보안 예외먼저 구분해야 할 것은, 보안에서 던져지는 예외가 성격이 다른 두 계열이라는 점입니다.예외상태 코드의미AuthenticationException401 Unauthorized"당신이 누구인지 모르겠다" (인증 실패/누락) Acces..
[Spring] Spring Security 인가 처리
·
Framework/Spring
안녕하세요.앞선 두 글에서 Spring Security의 전체 구조(FilterChain)와 인증(Authentication) 처리 흐름을 정리했습니다.이번에는 인증의 자연스러운 짝인 인가(Authorization)를 다룹니다.1편에서 FilterSecurityInterceptor를 "URL 접근 권한을 최종 판단한다" 한 줄로만 넘겼는데, 이번 글에서 그 한 줄을 펼쳐봅니다.이번에도 설정 암기보다 "인가 결정이 내부적으로 어떻게 내려지는가" 에 초점을 맞춥니다. 인가는 어디서 일어나는가1편의 필터 실행 순서를 다시 떠올려 보면, 인가는 보안 필터 체인의 거의 마지막 단계에서 일어납니다.요청 ↓인증 필터들 (누구인지 확정) ↓... (익명/세션/예외 변환 필터) ↓인가 필터 (이 작업을 해도 되는..