programing

PreAuthorize 오류 처리

testmans 2023. 3. 11. 08:45
반응형

PreAuthorize 오류 처리

사용하고 있다Spring Oauth2그리고.Spring Pre-post Annotations와 함께Spring-boot

서비스 클래스가 있습니다.MyService.중 하나MyService메서드는 다음과 같습니다.

@PreAuthorize("#id.equals(authentication.principal.id)")
public SomeResponse getExampleResponse(String id){...}

발신자 컨트롤러에 의해 반환되는 json을 어떤 방법으로 제어할 수 있습니까?

기본적으로 반환되는 json은 다음과 같습니다.

{error : "access_denied" , error_message: ".."}

제어가 가능해지고 싶다error_messageparam. 저는 다음과 같은 것을 찾고 있습니다.

@PreAuthorize(value ="#id.equals(authentication.principal.id)", onError ="throw new SomeException("bad params")")
public SomeResponse getExampleResponse(String id){...}

제가 생각한 방법 중 하나는 '사용하는 것입니다.ExceptionHandler

@ExceptionHandler(AccessDeniedException.class)
public Response handleAccessDeniedException(Exception ex, HttpServletRequest request){
    ...
}

하지만 난 통제할 수 없어message예외입니다.그리고 이게 정말 확실한지 모르겠어요.Exception향후 릴리즈에 추가될 예정입니다.

에러 처리에 관한 Spring Boot 문서:http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ #boot-boot-http-error-handling.JSON을 제어할 수 있는 방법 중 하나는,@Bean타입의ErrorAttributes.

@Bean
ErrorAttributes errorAttributes() {
    return new MyErrorAttributes();
}

Access Denied Handler 구현

@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException, ServletException {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    try {
        ObjectMapper mapper = new ObjectMapper();
        SomeJsonModel jsonResponse =new SomeJsonModel();
        mapper.writeValue(response.getOutputStream(), jsonResponse);
    } catch (Exception e) {
        throw new ServletException();
    }
}

SomeJsonModel은 사용자 고유의 POJO/모델 클래스가 됩니다.이 클래스는 리소스 서버 구성에서 접근이 거부된 핸들러를 제어합니다.

@Override
public void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
                .antMatchers(SECURED_PATTERN).and().authorizeRequests()
                .antMatchers(HttpMethod.POST,SECURED_PATTERN).access(SECURED_WRITE_SCOPE)
                .anyRequest().access(SECURED_READ_SCOPE).and()
              .exceptionHandling().authenticationEntryPoint(newAuthExceptionEntryPoint())
                .accessDeniedHandler(new MyAccessDeniedHandler());
}

Access Denied Handler를 구현했을 때 작동하지 않았습니다.그래서 AuthenticationEntryPoint 내에 ExceptionHandler 함수를 만들고 클래스를 @ControllerAdvice로 마킹했습니다.

아래에서 코드를 찾아주세요.

@ControllerAdvice
@Component  
public class EmrExceptionHandler implements AuthenticationEntryPoint {


    private static final Logger logger = LoggerFactory.getLogger(EmrExceptionHandler.class);

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                         AuthenticationException authException) throws IOException, ServletException {
        logger.error("Unauthorized error: {}", authException.getMessage());
        httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        httpServletResponse.getWriter().write(convertObjectToJson(new ErrorResponse(ResponseMessages.NOT_AUTHORIZED)));
    }

    @ExceptionHandler(value = {AccessDeniedException.class})
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                         AccessDeniedException accessDeniedException) throws IOException {
        logger.error("AccessDenied error: {}", accessDeniedException.getMessage());
        httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
        httpServletResponse.getWriter().write(convertObjectToJson(new ErrorResponse(ResponseMessages.NOT_PERMITTED)));
    }


    public String convertObjectToJson(Object object) throws JsonProcessingException {
        if (object == null) {
            return null;
        }
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }
}

언급URL : https://stackoverflow.com/questions/28410690/preauthorize-error-handling

반응형