- Spring Boot 3.2.1 + React 19 프로젝트 구조 - S&P Global Maritime API Bypass 및 Risk & Compliance Screening 기능 - 팀 워크플로우 v1.6.1 적용 (settings.json, hooks, workflow-version) - 프론트엔드 빌드 (Vite + TypeScript + Tailwind CSS) - 메인 카드 레이아웃 CSS Grid 전환 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 lines
2.5 KiB
Java
57 lines
2.5 KiB
Java
package com.snp.batch.global.config;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.security.authentication.DisabledException;
|
|
import org.springframework.security.authentication.LockedException;
|
|
import org.springframework.security.core.AuthenticationException;
|
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Basic Auth 인증 실패 시 계정 상태에 따라 구체적인 오류 정보를 JSON으로 반환하는 EntryPoint.
|
|
*
|
|
* <ul>
|
|
* <li>LockedException (accountLocked=true, 즉 SUSPENDED): ACCOUNT_SUSPENDED</li>
|
|
* <li>DisabledException (disabled=true, 즉 비활성/기간 만료): ACCOUNT_DISABLED</li>
|
|
* <li>그 외 (잘못된 자격증명 등): INVALID_CREDENTIALS</li>
|
|
* </ul>
|
|
*
|
|
* WWW-Authenticate 헤더를 유지하여 Swagger UI의 Basic Auth 다이얼로그와 호환성을 보장한다.
|
|
*/
|
|
public class BypassAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
@Override
|
|
public void commence(HttpServletRequest request, HttpServletResponse response,
|
|
AuthenticationException authException) throws IOException {
|
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
response.setCharacterEncoding("UTF-8");
|
|
// WWW-Authenticate 헤더를 보내지 않음 — 브라우저 네이티브 로그인 다이얼로그 방지
|
|
// Swagger UI는 자체 Authorize 메커니즘으로 Basic Auth를 처리함
|
|
|
|
String error;
|
|
String message;
|
|
|
|
if (authException instanceof LockedException) {
|
|
error = "ACCOUNT_SUSPENDED";
|
|
message = "정지된 계정입니다. 관리자에게 문의하세요.";
|
|
} else if (authException instanceof DisabledException) {
|
|
error = "ACCOUNT_DISABLED";
|
|
message = "비활성화된 계정입니다. 접근 기간이 만료되었거나 계정이 비활성 상태입니다.";
|
|
} else {
|
|
error = "INVALID_CREDENTIALS";
|
|
message = "사용자명 또는 비밀번호가 올바르지 않습니다.";
|
|
}
|
|
|
|
objectMapper.writeValue(response.getOutputStream(),
|
|
Map.of("error", error, "message", message));
|
|
}
|
|
}
|