3.2 KiB
3.2 KiB
title, source_type, status, related_branches, related_projects, tags, created, status_label
| title | source_type | status | related_branches | related_projects | tags | created | status_label | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| interview-prep / jwt-resource-server-fine-grained-error-classification | interview-prep | raw |
|
|
|
2026-06-08 | collecting |
interview-prep: jwt-resource-server-fine-grained-error-classification
Layer:
raw/interviews/— 면접 질문 원본 수집. 다듬은 답변은/interviewize후wiki/interview/.
Parent / 부모
- raw/branch-notes/feature-security-operational-baseline — JWT Resource Server 인증/인가 실패의 fine-grained 운영 분류 구현.
질문 / Question
- 질문 원문: JWT 인증 실패를 401 하나로 뭉개지 않고, 운영자가 missing/expired/signature/issuer/audience/unknown-kid 를 구분할 수 있게 어떻게 구현했나요? 클라이언트에는 무엇을 노출했나요?
- 출처: 예상 질문 (실제 면접 아님).
질문 의도 추론 / Why this question
- 핵심 평가 대상:
- Spring Security resource server 의 실패 처리 위치 이해 — bearer 토큰 검증 실패는
BearerTokenAuthenticationFilter/ExceptionTranslationFilter가AuthenticationEntryPoint로 보내며@RestControllerAdvice에 도달하지 않는다. 그래서 fine-grained 분류는 EntryPoint/AccessDeniedHandler 에 있어야 한다. - 보안 응답의 과노출 방지 — 클라이언트엔 generic message(
Authentication failed)만, 내부엔 분류 code. issuer/audience/token 값을 응답·로그에 흘리지 않기. - 표준 정합 — 401 은
WWW-AuthenticateMUST(RFC 9110 §15.5.2), transient(kid/jwks)엔Retry-After.
- Spring Security resource server 의 실패 처리 위치 이해 — bearer 토큰 검증 실패는
- 함정:
- "@RestControllerAdvice 에서
AuthenticationException잡으면 된다" — filter-layer 실패는 거기 안 온다. - exception → code 매핑을 message 문자열 heuristic 에 의존하는 것의 fragility 를 인정 안 함.
- clock skew 를 default 에 맡기고 "Spring 이 알아서" — 버전 업 시 silent drift.
- "@RestControllerAdvice 에서
- 후속 질문:
JwtValidationException과BadJwtException의 차이, 각각 어떤 실패인가?- unknown kid 를 왜 retryable=true + Retry-After 로 두나? (rotation 중 JWKS refresh 로 해소)
- clock skew 60s 를 명시 설정한 이유? (default 의존 시 drift)
- 다중 audience/validator 동시 실패 시 어떤 code 를 우선하나?
답변 재료 / Raw answer material
- 구현:
SecurityErrorClassifier(exception graph + validator/Nimbus message heuristic, 우선순위 expired>issuer>audience),EnvelopeAuthenticationEntryPoint/EnvelopeAccessDeniedHandler(공통AuthErrorResponseWriter→ Envelope JSON),JwtDecoderConfig(SupplierJwtDecoder로 lazy 60s clock skew + issuer + audience validator). - 12 code 는
docs/registries/error-codes.yamlSSOT 와OperationalErrorenum 일치(status/category/retryable). - redaction: 응답 body 는 generic message, 로그는 code/category/method/path 만 — token(
eyJ...) 미노출. contract test 로 강제. - 한계(솔직): message 문자열 heuristic 은 Spring/Nimbus 버전 메시지 변경에 취약 → unmapped 는 generic 401 fallback(절대 500 아님). 실 IdP 통합 테스트는 미수행(
prod-verified아님).