捕获AuthenticationProvider中引发的exception
我正在实现自定义’AuthenticationProvider’。 如果未经过身份validation,我会在“authenticate”函数中抛出exception,如下所示。
public class DelegatingLdapAuthenticationProvider implements AuthenticationProvider { private ActiveDirectoryLdapAuthenticationProvider primaryProvider; private List secondaryProviders = new ArrayList(); public DelegatingLdapAuthenticationProvider() { } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { Authentication result = null; AuthenticationException exception = null; try { result = primaryProvider.authenticate(authentication); } catch (AuthenticationException e) { exception = e; for (ActiveDirectoryLdapAuthenticationProvider secondaryProvider : secondaryProviders) { try { result = secondaryProvider.authenticate(authentication); if (result.isAuthenticated()) { break; } } catch (AuthenticationException e1) { exception = e; } } } if (result == null || !result.isAuthenticated()) { throw exception; } return result; }
我有全局exception处理程序,如下所示。
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({NoPermissionException.class}) @ResponseBody @ResponseStatus(value = HttpStatus.FORBIDDEN) public Map noPermission(NoPermissionException e) { return createErrorResponse(e, "Don't have permissions"); } @ExceptionHandler({Exception.class}) @ResponseBody @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) public Map exceptionInProcessing(Exception e) { return createErrorResponse(e, "Unable to process. Unknown error occurred: " + e.getMessage()); } private Map createErrorResponse(Exception e, String errorMessage) { Map errorResponse = new HashMap(); errorResponse.put("message", errorMessage); errorResponse.put("reason", e.toString()); return errorResponse; } }
当在“authenticate”函数内抛出exception时,不会调用全局exception处理程序。 对于所有其他exception,它被调用。 我想捕获全局exception处理程序中的exception并返回自定义错误消息。 我怎样才能做到这一点? 任何帮助赞赏。 提前致谢。
GlobalExceptionHandler
用于控制器exception处理程序,但AuthenticationProvider
仍处于filter中,如果要处理AuthenticationException
,则需要处理它以实现AuthenticationEntryPoint
并覆盖commence
方法。
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
AuthenticationException
和AccessDeniedException
已由ExceptionTranslationFilter
处理。 您只需要注入AuthenticationEntryPoint
和AccessDeniedHandler
(处理AccessDeniedException
)
或者您可以在filter中捕获这些exception,然后在文件管理器中处理它,如AbstractAuthenticationProcessingFilter
AuthenticationFailureHandler
在控制器exception处理程序有机会捕获exception之前调用身份validation提供程序。
您可以覆盖AuthenticationFailureHandler来处理安全filter链级别的exception,请查看示例
文档中描述的行为:
筛选器调用配置的AuthenticationManager来处理每个身份validation请求。 身份validation成功或身份validation失败后的目标分别由AuthenticationSuccessHandler和AuthenticationFailureHandler策略接口控制。 filter具有允许您设置这些属性的属性,以便您可以完全自定义行为
正如@chaoluo已经说过你需要实现AuthenticationEntryPoint
并覆盖begin方法。 如果要返回错误JSON对象,可以执行以下操作:
@Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType(MediaType.APPLICATION_JSON_VALUE); //create errorObj PrintWriter writer = response.getWriter(); mapper.writeValue(writer, errorObj); writer.flush(); }
- 当使用JtaTransactionManager时,为什么使用未在Spring服务中提交的EntityManager进行JPA更改?
- 春季启动。 HMAC认证。 如何添加自定义AuthenticationProvider和身份validationfilter?
- 将音频与video结合(无ffmpeg) – Java
- HttpSessionListener(sessionCreated / destroyed) – 奇怪的行为
- 在Java 8中使用多重inheritance
- Oracle ADF安全应用程序提供HTTP 401错误
- 当我运行.jar时,我得到一个“java.library.path中没有lwjgl”错误
- 使用ParameterExpression作为In子句的一部分
- 加载DOM库时log4j中的冲突? (不允许在classpath中实现dom的其他实现?)