Springsecurity之ExceptionTranslationFilter

    Springsecurity的版本是4.3.x,源碼能夠在Github上下載。java

一、ExceptionTranslationFilter的doFilter

 ExceptionTranslationFilter是個異常過濾器,用來處理在認證受權過程當中拋出的異常,ExceptionTranslationFilter後面的過濾器是FilterSecurityInterceptor。先上一張圖,以下圖1所示:ide

                                                              圖1ui

  • 紅框1中的,是調用Filter鏈中的後續Filter。
  • 若是圖1中的操做拋出異常,就會來到紅框2處,判斷拋出的異常是不是AuthenticationException。
  • 若是拋出的異常不是AuthenticationException,即紅框2的結果爲null,那麼就到紅框3處,判斷是不是AccessDeniedException。
  • 若是拋出的異常是AuthenticationException或者時AccessDeniedException,那麼執行紅框4處的代碼。

二、ExceptionTranslationFilter的handleSpringSecurityException方法

下面來看handleSpringSecurityException的方法體,以下List-1所示this

    List-1spa

private void handleSpringSecurityException(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain, RuntimeException exception)
			throws IOException, ServletException {
		if (exception instanceof AuthenticationException) {
			logger.debug(
					"Authentication exception occurred; redirecting to authentication entry point",
					exception);

			sendStartAuthentication(request, response, chain,
					(AuthenticationException) exception);
		}
		else if (exception instanceof AccessDeniedException) {
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			if (authenticationTrustResolver.isAnonymous(authentication) || authenticationTrustResolver.isRememberMe(authentication)) {
				logger.debug(
						"Access is denied (user is " + (authenticationTrustResolver.isAnonymous(authentication) ? "anonymous" : "not fully authenticated") + "); redirecting to authentication entry point",
						exception);

				sendStartAuthentication(
						request,
						response,
						chain,
						new InsufficientAuthenticationException(
							messages.getMessage(
								"ExceptionTranslationFilter.insufficientAuthentication",
								"Full authentication is required to access this resource")));
			}
			else {
				logger.debug(
						"Access is denied (user is not anonymous); delegating to AccessDeniedHandler",
						exception);

				accessDeniedHandler.handle(request, response,
						(AccessDeniedException) exception);
			}
		}
	}
  1. 若是拋出的異常是AuthenticationException,則執行方法sendStartAuthentication
  2. 若是拋出的異常是AccessDeniedException,且從SecurityContextHolder.getContext().getAuthentication()獲得的是AnonymousAuthenticationToken或者RememberMeAuthenticationToken,那麼執行sendStartAuthentication
  3. 若是上面的第二點不知足,則執行accessDeniedHandler的handle方法

三、ExceptionTranslationFilter的sendStartAuthentication方法

    以下List-2所示,會調用authenticationEntryPoint的commence方法。debug

    List-2code

protected void sendStartAuthentication(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain,
			AuthenticationException reason) throws ServletException, IOException {
		// SEC-112: Clear the SecurityContextHolder's Authentication, as the
		// existing Authentication is no longer considered valid
		SecurityContextHolder.getContext().setAuthentication(null);
		requestCache.saveRequest(request, response);
		logger.debug("Calling Authentication entry point.");
		authenticationEntryPoint.commence(request, response, reason);
	}

 

思考:

  1. 咱們有時候會在xml配置中配置accessDeniedHandler,是在這裏用到嗎?
  2. List-2中使用到的authenticationEntryPoint,是什麼?
相關文章
相關標籤/搜索