-
oauth2 자세한 플로우 체크Spring/Spring Security 2025. 8. 21. 16:03728x90반응형
용어 정리(중요)
- Authorization Server: 구글
- Client(또는 RP): 스프링 기반 웹 앱 (로그인 시작/콜백 처리 주체)
- Resource Server: 여러분 API 서버(액세스 토큰으로 보호 자원 제공). 실서비스에선 Client와 Resource Server가 같은 앱일 수도 있지만 역할은 구분해서 생각하세요.
- OIDC(OpenID Connect): “로그인(신원)”을 다루는 확장 규격. 구글 로그인은 사실상 OIDC 사용이 표준입니다.
보강된 전체 플로우
- 브라우저 → Client: 로그인 시작 (여러분 1과 동일)
- 로그인 버튼 클릭 → /oauth2/authorization/google 같은 엔드포인트 호출
- Client: 요청 컨텍스트 생성(중요)
- state 생성 후 서버 세션/스토리지에 보관(이후 콜백에서 CSRF 방지 용도)
- PKCE 사용 시 code_verifier 생성 및 보관, code_challenge 계산
- 필요 스코프 결정: 최소 openid email profile (OIDC)
- nonce 생성(권장, ID 토큰 재사용 공격 방지)
- Client → Authorization Server로 리다이렉트 (여러분 2)
- 파라미터: client_id, redirect_uri, response_type=code, scope, state, code_challenge(+method=S256), nonce 등
- 브라우저 → 구글 로그인/동의 화면 (여러분 3–5)
- 구글은 등록된 redirect_uri 인지 확인
- 사용자가 인증(로그인) + 동의 수행
- Authorization Server → 브라우저 → Client 콜백 (여러분 6)
- 콜백으로 code와 state 전달
- Client는 state를 검증(반드시 일치해야 함; 불일치 시 즉시 실패 처리)
- Client ↔ Authorization Server: 토큰 교환 (여러분 7의 일부)
- Token Endpoint로 code를 교환하여 access_token, id_token(OIDC), 필요 시 refresh_token 수령
- PKCE 사용 시: code_verifier를 함께 전송하여 검증 완료
- ID 토큰 검증(매우 중요)
- 서명 검증(구글 JWKS), iss, aud(client_id), exp, iat, nonce 확인
- 검증 실패 시 즉시 fail handler로
- 사용자 정보 획득 & 로컬 처리
- 선호 1: 검증한 ID 토큰의 클레임(sub, email, email_verified, name, picture 등)으로 사용자 매핑
- 선호 2: 필요 시 UserInfo Endpoint를 access_token으로 호출하여 프로필 보강
- loadUser(커스텀)에서:
- 신규면 회원가입(프로비저닝)
- 기존 사용자면 업데이트/로그인 진행
- 세션/토큰 발급 & 로그인 완료
- 서버 세션 기반이면 세션 생성 후 SuccessHandler로 후속 처리
- 토큰 기반이면 자체 세션 토큰/JWT 발급(단, 외부 id_token을 그대로 세션 토큰으로 쓰지 말 것)
- 쿠키 보안: Secure, HttpOnly, SameSite=Lax(or Strict) 권장, HTTPS 필수
- 리소스 접근(필요 시)
- 브라우저가 API(Resource Server)에 요청 시, 서버 측에서 내부 세션 검증 또는 액세스 토큰 검증
- 마이크로서비스라면 API 게이트웨이/리소스 서버에서 JWT 검증 수행
- 토큰 갱신(옵션)
- 오프라인 액세스가 필요하면 access_type=offline로 refresh_token을 받고, 만료 시 토큰 리프레시
- 웹 브라우저 기반에선 refresh token을 브라우저에 노출하지 않도록 주의(서버 보관)
- 오류 처리 & 예외 플로우(필수)
- 콜백에 error=access_denied 등 수신 시 사용자 친화적 에러 페이지
- state/nonce 불일치, ID 토큰 만료/서명 실패 → fail handler
- 재시도 전략: 네트워크 오류, 구글 JWKS 키 회전(캐시 & 실패 시 재조회)
- 시계 오차 허용(예: ±2–5분)
- 로그아웃 & 연결 해제(옵션)
- 애플리케이션 세션/쿠키 삭제
- 필요 시 구글 측 토큰 철회(Revocation Endpoint) 지원
- 전역 로그아웃은 공급자 정책을 따르되, UX를 명확히
여러분이 쓴 흐름에 보완이 필요한 핵심 포인트만 콕 집어서
- Client vs Resource Server 역할 구분: “로그인(OIDC)”을 시작/처리하는 주체는 Client입니다. 보호 자원을 제공하는 건 Resource Server 역할입니다. 하나의 스프링 앱에서 둘 다 할 수 있지만, 개념은 분리해서 관리하세요.
- PKCE, state, nonce: 최근 권장 보안 셋. 최소한 state, 가급적 PKCE와 nonce를 꼭 넣으세요.
- ID 토큰 검증: OIDC 로그인 핵심. 단순히 code로 “정보 받아오기”만 하면 부족합니다. ID 토큰의 서명·클레임 검증이 필수입니다.
- 세션/쿠키 보안: Secure, HttpOnly, SameSite 설정과 HTTPS 강제.
- 오류·키회전 처리: JWKS 키 회전, 시계 오차, 재시도(백오프) 고려.
- 토큰 저장 위치: 브라우저 로컬스토리지에 장기 토큰 저장 지양. 서버 보관 또는 httpOnly 쿠키 기반 세션 선호.
Spring Security(OAuth2 Client/OIDC) 적용 시 체크리스트(짧게)
- spring-boot-starter-oauth2-client + (리소스 서버라면) spring-boot-starter-oauth2-resource-server
- application.yml
- spring.security.oauth2.client.registration.google (client-id, client-secret, scope: openid, email, profile)
- provider.google(issuer-uri 사용 시 자동 설정)
- oauth2Login() 사용 + Success/Failure Handler 커스터마이징
- JwtDecoder(Resource Server) 또는 OIDC ID 토큰 검증 설정
- CSRF, CORS, 쿠키 정책 점검
필요하시면 Spring Security 설정 예시(yaml/Java)와 SuccessHandler/FailureHandler/loadUser 커스텀 샘플도 바로 드릴게요.
728x90반응형