处理401错误(Spring Security)

我可以处理404错误。

@ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(NoHandlerFoundException.class) @ResponseBody public void noHandlerFoundException (HttpServletResponse response) throws IOException{ //some code } 

但是如何处理401错误?

编辑我使用的是Java而不是web.xml

编辑我应该在NoHandlerFoundException中放置什么来处理HttpStatus.UNAUTHORIZED

编辑

validation失败时,我的方法不成功validation:

 public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { SecurityContextHolder.clearContext(); if (logger.isDebugEnabled()) { logger.debug("Authentication request failed: " + failed.toString()); logger.debug("Updated SecurityContextHolder to contain null Authentication"); logger.debug("Delegating to authentication failure handler " + failureHandler); } // response.setCharacterEncoding("UTF-8"); // response.getWriter().write(jsonService.toString(jsonService.getResponse(false, "Не удалось авторизоваться", "401"))); rememberMeServices.loginFail(request, response); failureHandler.onAuthenticationFailure(request, response, failed); } } 

此代码发送401错误html。 我需要发送json,你可以在评论中看到它。

这是一个完整的处理程序,适用于所有一小部分错误页面:

 @Controller public class ErrorCodeController extends BaseController { @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage400", method=RequestMethod.GET) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public String handleBadRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.BAD_REQUEST); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage401", method=RequestMethod.GET) @ResponseStatus(value=HttpStatus.UNAUTHORIZED,reason="Unauthorized Request") public String handleUnauthorizedRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.UNAUTHORIZED); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage404", method=RequestMethod.GET) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleNotFoundRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.NOT_FOUND); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage500", method=RequestMethod.GET) @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR,reason="Internal Server Error") public String handleInternalServerError(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.INTERNAL_SERVER_ERROR); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) public void handleApplicationExceptions(Throwable exception, HttpServletResponse response) { } private String processErrorCodes(ApplicationException ex,HttpServletResponse response, ModelMap map){ map.addAttribute("class", ClassUtils.getShortName(ex.getClass())); map.addAttribute("message", ex.getMessage()); map.addAttribute("errorMessage", ex.getErrorMessage()); map.addAttribute("errorCode", ex.getErrorCode()); map.addAttribute("timestamp", ex.getCurrentDate()); return "errorPage"; } } 

基础控制器:

 @Controller @RequestMapping("/") public class BaseController { // Remember to add any exception that you suspect can be thrown in this web application. @ExceptionHandler({ApplicationException.class,NullPointerException.class}) public ModelAndView handleException(Throwable exception,HttpServletRequest req) { ModelMap model = new ModelMap(); ApplicationException ex = new ApplicationException(); String timeStamp = ex.getCurrentDate().toString(); //String temp = ClassUtils.getShortName(ex.getClass()); //model.addAttribute("class", ClassUtils.getShortName(ex.getClass())); model.addAttribute("timeStamp", timeStamp); return new ModelAndView("errorPage", model); } 

Web.xml:

  myApp  400 /errorPage400.xhtml   401 /errorPage401.xhtml   404 /errorPage404.xhtml   500 /errorPage500.xhtml   java.lang.Throwable /errorPage.xhtml  

我知道这是一个古老的话题,但我也是如此,所以这里的解决方案只适用于Tomcat。

*DispatcherServletInitializer / WebAppInitializer#onStartup(...)方法中调用以下方法。

 Field appContextInFacade = ApplicationContextFacade.class.getDeclaredField("context"); appContextInFacade.setAccessible(true); ApplicationContext appContext = (ApplicationContext) appContextInFacade.get(servletContext); Field appContextInContext = ApplicationContext.class.getDeclaredField("context"); appContextInContext.setAccessible(true); StandardContext context = (StandardContext) appContextInContext.get(appContext); ErrorPage defaultErrorPage = new ErrorPage(); defaultErrorPage.setLocation("/myinternalerrorhandlercontroller"); context.addErrorPage(defaultErrorPage); // You may have to use reflection here as well. 

然后添加一个能够处理这些错误请求的控制器:

 @RequestMapping("/myinternalerrorhandlercontroller") public ResponseEntity renderErrorPage(HttpServletRequest httpRequest) 

您可以使用以下方法提取错误详细信

 (Integer) httpRequest.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); 

重要的提醒:

  • 您必须处理所有RequestMethod
  • 您必须处理所有Content-Type s(=>返回字节或注册一个回退HttpMessageConverter,它可以将您的错误对象转换为json,无论请求的是什么)。
  • 您的错误页面绝不能抛出exception或无法返回响应。
  • 仅当未调用常用的@ExceptionHandler或类似机制或(无法执行)时,才会显示错误页面。
  • 不要访问应用程序状态,例如用户身份validation,因为您不在其范围内,并且可能无法使用或包含无效数据。

你可以查一下

 HttpStatus.UNAUTHORIZE 

请参阅: 有关HttpStatus的信息(Spring Framework)