预授权错误处理
PreAuthorize error handling
我正在使用 Spring Oauth2
和 Spring Pre-post Annotations
以及 Spring-boot
我有一项服务 class MyService
。 MyService
方法之一是:
@PreAuthorize("#id.equals(authentication.principal.id)")
public SomeResponse getExampleResponse(String id){...}
我能否以某种方式控制调用方控制器返回的 json?
默认返回的json是:
{error : "access_denied" , error_message: ".."}
我希望能够控制 error_message
参数。我正在寻找类似于以下内容的内容:
@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 关于错误处理的引导文档:http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling。控制 JSON 的一种方法是添加 ErrorAttributes
.
类型的 @Bean
@Bean
ErrorAttributes errorAttributes() {
return new MyErrorAttributes();
}
实施 AccessDeniedHandler
@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/model class,您可以控制
并在资源服务器配置中添加拒绝访问处理程序
@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());
}
当我实施 AccessDeniedHandler 时它对我不起作用。所以我在 AuthenticationEntryPoint 中创建了一个 ExceptionHandler 函数并将 class 标记为
@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);
}
}
我正在使用 Spring Oauth2
和 Spring Pre-post Annotations
以及 Spring-boot
我有一项服务 class MyService
。 MyService
方法之一是:
@PreAuthorize("#id.equals(authentication.principal.id)")
public SomeResponse getExampleResponse(String id){...}
我能否以某种方式控制调用方控制器返回的 json?
默认返回的json是:
{error : "access_denied" , error_message: ".."}
我希望能够控制 error_message
参数。我正在寻找类似于以下内容的内容:
@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 关于错误处理的引导文档:http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling。控制 JSON 的一种方法是添加 ErrorAttributes
.
@Bean
@Bean
ErrorAttributes errorAttributes() {
return new MyErrorAttributes();
}
实施 AccessDeniedHandler
@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/model class,您可以控制 并在资源服务器配置中添加拒绝访问处理程序
@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());
}
当我实施 AccessDeniedHandler 时它对我不起作用。所以我在 AuthenticationEntryPoint 中创建了一个 ExceptionHandler 函数并将 class 标记为 @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);
}
}