인증/권한 업무 규칙과 전환 불변식 추출 (codex-bais-final3-20260713-192718-BAIS-SPRING-ANA-AUTH-001)
All checks were successful
ci / test (pull_request) Successful in 5s

This commit is contained in:
forge-bot 2026-07-13 10:30:37 +00:00
parent 9d2e1fd4ff
commit f2bec9f746

View file

@ -0,0 +1,46 @@
package com.example.auth.security;
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.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.time.Instant;
import java.util.Map;
/**
* Custom Access Denied Handler - preserves error response format.
* Maps to AUTH_030, AUTH_031, AUTH_040, AUTH_041 error codes.
*/
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
private final ObjectMapper objectMapper;
public CustomAccessDeniedHandler(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
Map<String, Object> errorResponse = Map.of(
"code", "AUTH_030",
"message", "Insufficient permissions",
"timestamp", Instant.now().toString(),
"path", request.getRequestURI()
);
objectMapper.writeValue(response.getOutputStream(), errorResponse);
}
}