ExceptionTranslationFilter
ExceptionTranslationFilter(Security Filter)允许将AccessDeniedException和AuthenticationException转换为HTTP响应。ExceptionTranslationFilter作为Security Filters之一插入到FilterChainProxy中。

- 首先,
ExceptionTranslationFilter调用FilterChain.doFilter(request, response),即调用应用程序的其余部分(出现异常才执行自己的逻辑)。


- 如果用户未经身份验证或是身份验证异常,则启动身份验证。
- 清除
SecurityContextHolder的身份验证(SEC-112:清除SecurityContextHolder的身份验证,因为现有身份验证不再有效)。 - 将
HttpServletRequest保存在RequestCache中。当用户成功进行身份验证时,RequestCache用于重现原始请求。 AuthenticationEntryPoint用于从客户端请求凭据。例如,它可能会重定向到登录页面或发送WWW-Authenticate标头。

- 清除
- 否则,如果是
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对应的

本文介绍了Spring Security中的ExceptionTranslationFilter及其角色,重点解析了AuthenticationEntryPoint接口,包括BasicAuthenticationEntryPoint、DelegatingAuthenticationEntryPoint、DigestAuthenticationEntryPoint、Http403ForbiddenEntryPoint和LoginUrlAuthenticationEntryPoint的用法。通过对formLogin和Basic认证的Debug分析,展示了身份验证流程。文章适合对Spring Security感兴趣的开发者阅读。
最低0.47元/天 解锁文章
8456

被折叠的 条评论
为什么被折叠?



