Spring Security:身份验证入口AuthenticationEntryPoint介绍与Debug分析

本文深入探讨了Spring Security的ExceptionTranslationFilter和AuthenticationEntryPoint接口,详细介绍了BasicAuthenticationEntryPoint、DelegatingAuthenticationEntryPoint、DigestAuthenticationEntryPoint等身份验证入口点的用法,并通过Debug分析了formLogin和Basic认证流程,帮助读者理解Spring Security的身份验证机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ExceptionTranslationFilter

ExceptionTranslationFilterSecurity Filter)允许将AccessDeniedExceptionAuthenticationException转换为HTTP响应。ExceptionTranslationFilter作为Security Filters之一插入到FilterChainProxy中。

在这里插入图片描述

  1. 首先,ExceptionTranslationFilter调用FilterChain.doFilter(request, response),即调用应用程序的其余部分(出现异常才执行自己的逻辑)。
    在这里插入图片描述
    在这里插入图片描述
  2. 如果用户未经身份验证或是身份验证异常,则启动身份验证。
    在这里插入图片描述
    1. 清除SecurityContextHolder的身份验证(SEC-112:清除SecurityContextHolder的身份验证,因为现有身份验证不再有效)。
    2. HttpServletRequest保存在RequestCache中。当用户成功进行身份验证时,RequestCache用于重现原始请求。
    3. AuthenticationEntryPoint用于从客户端请求凭据。例如,它可能会重定向到登录页面或发送WWW-Authenticate标头。
      在这里插入图片描述
  3. 否则,如果是AccessDeniedException,则拒绝访问。调用AccessDeniedHandler来处理拒绝的访问。
    在这里插入图片描述

想要了解Spring Security的过滤器链如何在Spring应用程序中发挥作用,可以阅读下面这篇博客:

AuthenticationEntryPoint

ExceptionTranslationFilter会使用AuthenticationEntryPoint启动身份验证方案。

public interface AuthenticationEntryPoint {
	/**
	 * 启动身份验证方案
	 * 实现应根据需要修改ServletResponse的标头以开始身份验证过程
	 */
	void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException;
}

BasicAuthenticationEntryPoint

ExceptionTranslationFilter用于通过BasicAuthenticationFilter开始身份验证。一旦使用BASIC对用户代理进行身份验证,可以发送未经授权的 (401) 标头,最简单的方法是调用BasicAuthenticationEntryPoint类的commence方法。 这将向浏览器指示其凭据不再被授权,导致它提示用户再次登录。

public class BasicAuthenticationEntryPoint implements AuthenticationEntryPoint,
		InitializingBean {
	// 领域名称
	private String realmName;

	// 检查属性
	public void afterPropertiesSet() {
		Assert.hasText(realmName, "realmName must be specified");
	}

	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException {
		// 填充响应
		response.addHeader("WWW-Authenticate", "Basic realm="" + realmName + """);
		response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
	}
	...
}

DelegatingAuthenticationEntryPoint

AuthenticationEntryPoint实现,它根据RequestMatcher匹配(委托)一个具体的AuthenticationEntryPoint

public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPoint,
		InitializingBean {
	private final Log logger = LogFactory.getLog(getClass());

    // RequestMatcher与AuthenticationEntryPoint的映射
	private final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints;
	// 默认AuthenticationEntryPoint
	private AuthenticationEntryPoint defaultEntryPoint;
    // 构造方法
	public DelegatingAuthenticationEntryPoint(
			LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints) {
		this.entryPoints = entryPoints;
	}

	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
        // 遍历entryPoints
		for (RequestMatcher requestMatcher : entryPoints.keySet()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Trying to match using " + requestMatcher);
			}
			// 如果RequestMatcher匹配请求
			if (requestMatcher.matches(request)) {
			    // 获取匹配请求的RequestMatcher对应的AuthenticationEntryPoint
				Auth
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值