org.springframework.security.web.AuthenticationEntryPoint在spring-security-web里面,分析的版本是5.0。java
List-1web
package org.springframework.security.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; public interface AuthenticationEntryPoint { void commence(HttpServletRequest var1, HttpServletResponse var2, AuthenticationException var3) throws IOException, ServletException; }
当用户请求了一个受保护的资源,可是用户没有经过认证,那么抛出异常,AuthenticationEntryPoint. Commence(..)就会被调用。这个对应的代码在ExceptionTranslationFilter中,以下List-2,当ExceptionTranslationFilter catch到异常后,就会间接调用AuthenticationEntryPoint。spring
List-2app
public class ExceptionTranslationFilter extends GenericFilterBean { private AuthenticationEntryPoint authenticationEntryPoint; ...... public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; try { chain.doFilter(request, response); this.logger.debug("Chain processed normally"); } catch (IOException var9) { throw var9; } catch (Exception var10) { ...... this.handleSpringSecurityException(request, response, chain, (RuntimeException)ase); } } private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response, FilterChain chain, RuntimeException exception) throws IOException, ServletException { ...... this.sendStartAuthentication(request, response, chain, (AuthenticationException)exception); ...... } protected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, AuthenticationException reason) throws ServletException, IOException { SecurityContextHolder.getContext().setAuthentication((Authentication)null); this.requestCache.saveRequest(request, response); this.logger.debug("Calling Authentication entry point."); this.authenticationEntryPoint.commence(request, response, reason); } ......
因此,咱们能够经过定义AuthenticationEntryPoint统一处理抛出的异常,以下List-3ide
List-3this
@Component @AllArgsConstructor public class CustomAuthExceptionEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { response.setCharacterEncoding(CommonConstants.UTF8); response.setContentType(CommonConstants.CONTENT_TYPE); R<String> result = new R<>(); result.setCode(HttpStatus.HTTP_UNAUTHORIZED); if (authException != null) { result.setMsg("error"); result.setData(authException.getMessage()); } response.setStatus(HttpStatus.HTTP_UNAUTHORIZED); PrintWriter printWriter = response.getWriter(); printWriter.append(JSONObject.toString(result)); } }