SpringBoot3-Security之异常处理ExceptionTranslationFilter


前言

本文主要研究异常处理过滤器 ExceptionTranslationFilter


一、ExceptionTranslationFilter 做了什么

这就不得不提另外一个过滤器 -> 鉴权过滤器 AuthorizationFilter, ExceptionTranslationFilter 是用来处理鉴权失败抛出的异常的过滤器

二、源码解析

ExceptionTranslationFilter#doFilter

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
	try {
		// 直接执行下面的过滤器, 这个过滤器后面就只剩一个 AuthorizationFilter
		chain.doFilter(request, response);
	}
	// 抛出异常之后处理
	// IO异常直接抛出
	catch (IOException ex) {
		throw ex;
	}
	catch (Exception ex) {
		// Try to extract a SpringSecurityException from the stacktrace
		Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
		// 找到抛出的到底是什么异常
		RuntimeException securityException = (AuthenticationException) this.throwableAnalyzer
			.getFirstThrowableOfType(AuthenticationException.class, causeChain);
		if (securityException == null) {
			securityException = (AccessDeniedException) this.throwableAnalyzer
				.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
		}
		if (securityException == null) {
			rethrow(ex);
		}
		if (response.isCommitted()) {
			throw new ServletException("Unable to handle the Spring Security Exception "
					+ "because the response is already committed.", ex);
		}
		// 抛出异常后的处理
		handleSpringSecurityException(request, response, chain, securityException);
	}
}

ExceptionTranslationFilter#handleSpringSecurityException

private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response,
		FilterChain chain, RuntimeException exception) throws IOException, ServletException {
	// 如果是认证异常, 最后会重定向到登录页, 但是我看 AuthorizationFilter 也没有抛出这个异常, 可能是没有看完, 后面还待研究
	if (exception instanceof AuthenticationException) {
		handleAuthenticationException(request, response, chain, (AuthenticationException) exception);
	}
	// 访问被拒绝, 也就是没有权限的异常
	else if (exception instanceof AccessDeniedException) {
		handleAccessDeniedException(request, response, chain, (AccessDeniedException) exception);
	}
}

ExceptionTranslationFilter#handleAuthenticationException

private void handleAuthenticationException(HttpServletRequest request, HttpServletResponse response,
			FilterChain chain, AuthenticationException exception) throws ServletException, IOException {
		// 重定向到登录页
		sendStartAuthentication(request, response, chain, exception);
	}

ExceptionTranslationFilter#handleAccessDeniedException

private void handleAccessDeniedException(HttpServletRequest request, HttpServletResponse response,
		FilterChain chain, AccessDeniedException exception) throws ServletException, IOException {
	Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
	boolean isAnonymous = this.authenticationTrustResolver.isAnonymous(authentication);
	// 如果是匿名, 重定向到登录页
	if (isAnonymous || this.authenticationTrustResolver.isRememberMe(authentication)) {
		// 重定向到登录页
		sendStartAuthentication(request, response, chain, xxx);
	}
	else {
		// 鉴权失败处理器处理: 一般是返回给浏览器一个 403 的状态码
		this.accessDeniedHandler.handle(request, response, exception);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值