SprngSecurity报错直接跳转到登陆地址并且没有任何提示

今天在SpringSecurity框架 弄个验证码生成的功能,然后就一直不行,一直跳向登陆地址,也没有报错信息,找了大半天什么都试过,后来才发现时你未认证时如果你得代码抛出了AuthenticationException及其子类时他会跳像登陆地址,异常信息也会丢掉!遇到这种坑B问题只能傻眼了!

首先我得代码是这样的

    /**
     *  根据类型获取验证码处理器
     * @param type 验证码类型
     * @return
     */
    public ValidateCodeProcessor findValidateCodeProcessor(String type){
     
        String name = type.toLowerCase() + ValidateCodeProcessor.class.getSimpleName();
        ValidateCodeProcessor validateCodeProcessor = validateCodeProcessorMap.get(name);
        if(validateCodeProcessor == null){
     
            throw new ValidateCodeException("验证码处理器" + name + "不存在");
        }
        return validateCodeProcessor;
    }

此时如果 validateCodeProcessor 为空则会抛出一个异常,这个异常是AuthenticationException的子类,注意是子类是子类,然后我这没写对,抛出了这个异常!

这个时候就会来到
org.springframework.security.web.access.ExceptionTranslationFilter#doFilter
的catch代码块

	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);
		}
		catch (IOException ex) {
     
			throw ex;
		}
		catch (Exception ex) {
     
 		// spring会把你抛出的异常包装好几层,所以下面这几段代码在拿你抛的那个异常,也就是上面的ValidateCodeException
			Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex);
			RuntimeException ase = (AuthenticationException) throwableAnalyzer
					.getFirstThrowableOfType(AuthenticationException.class, causeChain);
			// 这里肯定不等于空,不等于空,他就去调用Spring Security的异常处理器
			if (ase != null) {
     
				handleSpringSecurityException(request, response, chain, ase);
			}
		 
		}
	}

	private void handleSpringSecurityException(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain, RuntimeException exception)
			throws IOException, ServletException {
     
		if (exception instanceof AuthenticationException) {
     
			sendStartAuthentication(request, response, chain,
					(AuthenticationException) exception);
		}
	
	}

protected void sendStartAuthentication(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain,
			AuthenticationException reason) throws ServletException, IOException {
      
		// 将认证信息设置为空
		SecurityContextHolder.getContext().setAuthentication(null);
		// 缓存这个请求和响应,等会他会创建一个新的请求,
		requestCache.saveRequest(request, response);
		// 这个是关键,他会掉这个方法,使用的是这个类   LoginUrlAuthenticationEntryPoint
	 	authenticationEntryPoint.commence(request, response, reason);
	}


现在来看 LoginUrlAuthenticationEntryPoint 这个类做了什么

	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
     
			
		String redirectUrl = null;
	 
		// 这里他会获取你配置的登陆地址,
		redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
		// 重定向到登陆页
		redirectStrategy.sendRedirect(request, response, redirectUrl);
	}

看完上面的解释,所以如果你的接口是想让他匿名访问(未认证时)的,那么你千万千万别抛AuthenticationException的子类异常,比如获取验证码,我这就是获取验证码的问题!不然你抛出的异常信息也不会打印,直接就跳转到登陆地址!

你可能感兴趣的:(spring,security,Spring,security)