概述
AbstractAuthenticationTargetUrlRequestHandler是Spring Security Web提供的一个抽象类,它主要实现了这样一种策略 :
认证动作成功时使用一个跳转策略跳转到指定的URL。
该策略实现对应的具体实现方法是 :
// AbstractAuthenticationTargetUrlRequestHandler 代码片段
protected void handle(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// 计算跳转目标URL : targetUrl
String targetUrl = determineTargetUrl(request, response);
if (response.isCommitted()) {
// 如果响应对象已经提交,则什么都不做,输出debug日志后直接返回
logger.debug("Response has already been committed. Unable to redirect to "
+ targetUrl);
return;
}
// 使用指定的跳转策略跳转到目标url : targetUrl
redirectStrategy.sendRedirect(request, response, targetUrl);
}
Spring Security Web 基于AbstractAuthenticationTargetUrlRequestHandler有两个实现子类 :
SimpleUrlAuthenticationSuccessHandler– 登录成功时跳转到指定URL参考
UsernamePasswordAuthenticationFilter对SavedRequestAwareAuthenticationSuccessHandler的使用,
SavedRequestAwareAuthenticationSuccessHandler是SimpleUrlAuthenticationSuccessHandler的子类。SimpleUrlLogoutSuccessHandler– 退出成功时跳转到指定URL参考
LogoutFilter对LogoutSuccessHandler的使用。
源代码
源代码版本 : Spring Security Web 5.1.4 RELEASE
package org.springframework.security.web.authentication;
// 省略 import 行
public abstract class AbstractAuthenticationTargetUrlRequestHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
// 如果通过请求参数指定跳转目标URL,使用此属性指定相应的参数名称,可以设置,
// 缺省值为 null, 表示不分析请求参数中指定的跳转目标URL
private String targetUrlParameter = null;
// 缺省跳转目标 URL,可以设置,
// 缺省值一般使用 /
private String defaultTargetUrl = "/";
// 是否总是使用缺省跳转目标 URL,也就是属性 defaultTargetUrl ,可以设置,
// 缺省值一般使用 false
private boolean alwaysUseDefaultTargetUrl = false;
// 是否使用头部 Referer ,可以设置,
// 缺省值一般使用 false
private boolean useReferer = false;
// 跳转策略,可以设置,,
// 缺省使用 DefaultRedirectStrategy
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
protected AbstractAuthenticationTargetUrlRequestHandler() {
}
/**
* Invokes the configured {@code RedirectStrategy} with the URL returned by the
* {@code determineTargetUrl} method.
* <p>
* The redirect will not be performed if the response has already been committed.
*/
protected void handle(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// 计算跳转目标URL : targetUrl
String targetUrl = determineTargetUrl(request, response);
if (response.isCommitted()) {
// 如果响应对象已经提交,则什么都不做,输出debug日志后直接返回
logger.debug("Response has already been committed. Unable to redirect to "
+ targetUrl);
return;
}
// 使用指定的跳转策略跳转到目标url : targetUrl
redirectStrategy.sendRedirect(request, response, targetUrl);
}
/**
* Builds the target URL according to the logic defined in the main class Javadoc.
*/
protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response) {
// 如果被设置要求总是使用缺省跳转目标url,则返回缺省跳转目标url : defaultTargetUrl
if (isAlwaysUseDefaultTargetUrl()) {
return defaultTargetUrl;
}
// Check for the parameter and use that if available
String targetUrl = null;
// 如果属性 targetUrlParameter 不为 null, 说明被设置成需要从请求参数中分析跳转目标url
if (targetUrlParameter != null) {
targetUrl = request.getParameter(targetUrlParameter);
if (StringUtils.hasText(targetUrl)) {
// 如果从请求参数中分析得到跳转目标url,返回该url
logger.debug("Found targetUrlParameter in request: " + targetUrl);
return targetUrl;
}
}
// 如果被设置为要使用请求头部 Referer 模式,并且目标 url 尚未分析得到,
// 则尝试从请求头部 Referer 获取跳转目标url
if (useReferer && !StringUtils.hasLength(targetUrl)) {
targetUrl = request.getHeader("Referer");
logger.debug("Using Referer header: " + targetUrl);
}
// 如果经过以上各种分析逻辑,仍未确定跳转目标url,则跳转目标url使用缺省跳转url,
// 也就是 defaultTargetUrl
if (!StringUtils.hasText(targetUrl)) {
targetUrl = defaultTargetUrl;
logger.debug("Using default Url: " + targetUrl);
}
return targetUrl;
}
/**
* Supplies the default target Url that will be used if no saved request is found or
* the {@code alwaysUseDefaultTargetUrl} property is set to true. If not set, defaults
* to {@code /}.
*
* @return the defaultTargetUrl property
*/
protected final String getDefaultTargetUrl() {
return defaultTargetUrl;
}
/**
* Supplies the default target Url that will be used if no saved request is found in
* the session, or the {@code alwaysUseDefaultTargetUrl} property is set to true. If
* not set, defaults to {@code /}. It will be treated as relative to the web-app's
* context path, and should include the leading <code>/</code>. Alternatively,
* inclusion of a scheme name (such as "http://" or "https://") as the prefix will
* denote a fully-qualified URL and this is also supported.
*
* @param defaultTargetUrl
*/
public void setDefaultTargetUrl(String defaultTargetUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultTargetUrl),
"defaultTarget must start with '/' or with 'http(s)'");
this.defaultTargetUrl = defaultTargetUrl;
}
/**
* If <code>true</code>, will always redirect to the value of {@code defaultTargetUrl}
* (defaults to <code>false</code>).
*/
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
}
protected boolean isAlwaysUseDefaultTargetUrl() {
return alwaysUseDefaultTargetUrl;
}
/**
* If this property is set, the current request will be checked for this a parameter
* with this name and the value used as the target URL if present.
*
* @param targetUrlParameter the name of the parameter containing the encoded target
* URL. Defaults to null.
*/
public void setTargetUrlParameter(String targetUrlParameter) {
if (targetUrlParameter != null) {
Assert.hasText(targetUrlParameter, "targetUrlParameter cannot be empty");
}
this.targetUrlParameter = targetUrlParameter;
}
protected String getTargetUrlParameter() {
return targetUrlParameter;
}
/**
* Allows overriding of the behaviour when redirecting to a target URL.
*/
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
/**
* If set to {@code true} the {@code Referer} header will be used (if available).
* Defaults to {@code false}.
*/
public void setUseReferer(boolean useReferer) {
this.useReferer = useReferer;
}
}
本文深入探讨了Spring Security中的AbstractAuthenticationTargetUrlRequestHandler类,它是处理认证成功后跳转的核心组件。文章详细分析了其工作原理,包括如何确定跳转URL、何时使用默认URL以及如何利用请求参数和HTTP头部来定制跳转行为。此外,还介绍了两个具体实现:SimpleUrlAuthenticationSuccessHandler和SimpleUrlLogoutSuccessHandler,分别用于登录和登出后的页面跳转。
5812

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



