SavedRequestAwareAuthenticationSuccessHandler源码分析

源码分析

这个SavedRequestAwareAuthenticationSuccessHandler类是一个自定义的认证成功处理器,它继承自Spring Security的SimpleUrlAuthenticationSuccessHandler。这个类的主要功能是在用户认证成功后,尝试从请求缓存中获取用户最初尝试访问的URL(即被保护的资源),然后将用户重定向到该URL,而不是默认的成功页面。

以下是对这个类的详细讲解:

  1. 成员变量:
    • logger:用于记录日志的Log对象,方便在代码中打印日志信息。
    • requestCache:一个RequestCache对象,用于在认证过程中保存和获取用户最初尝试访问的URL。这里默认使用HttpSessionRequestCache,它使用HTTP会话来存储请求。
  2. onAuthenticationSuccess方法:
    • 当用户认证成功时,该方法会被调用。
    • 首先,从requestCache中尝试获取用户最初尝试访问的SavedRequest对象。
    • 如果savedRequestnull(即没有保存任何请求),则调用父类SimpleUrlAuthenticationSuccessHandleronAuthenticationSuccess方法,通常这会将用户重定向到默认的成功页面。
    • 如果savedRequest不为null,则进一步检查是否应该使用默认的目标URL。这通过检查两个条件来实现:
      • isAlwaysUseDefaultTargetUrl()方法返回true(即始终使用默认的目标URL)。
      • 存在一个目标URL参数(通过getTargetUrlParameter()方法获取),并且该参数在请求中存在且有值。
    • 如果上述任一条件为真,则从requestCache中移除保存的请求,并调用父类的onAuthenticationSuccess方法。
    • 如果上述条件都不满足,则清除与认证相关的请求属性(通过clearAuthenticationAttributes方法),并使用savedRequest中的重定向URL(通过getRedirectUrl方法获取)将用户重定向到最初尝试访问的页面。这通过getRedirectStrategy().sendRedirect方法实现。
  3. setRequestCache方法:
    • 这是一个setter方法,用于设置requestCache对象。这使得外部可以注入自定义的RequestCache实现,以满足特定的需求。

这个类的主要用途是提升用户体验,因为它允许用户在认证成功后直接访问他们最初尝试访问的资源,而不是总是被重定向到默认的成功页面。这在用户需要访问多个受保护的资源时特别有用,因为他们不需要在每次认证后都重新导航到他们想要的页面。

源码内容

代码语言:javascript代码运行次数:0运行复制
/**
 * An authentication success strategy which can make use of the
 * {@link org.springframework.security.web.savedrequest.DefaultSavedRequest} which may
 * have been stored in the session by the {@link ExceptionTranslationFilter}. When such a
 * request is intercepted and requires authentication, the request data is stored to
 * record the original destination before the authentication process commenced, and to
 * allow the request to be reconstructed when a redirect to the same URL occurs. This
 * class is responsible for performing the redirect to the original URL if appropriate.
 * <p>
 * Following a successful authentication, it decides on the redirect destination, based on
 * the following scenarios:
 * <ul>
 * <li>If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
 * {@code defaultTargetUrl} will be used for the destination. Any
 * {@code DefaultSavedRequest} stored in the session will be removed.</li>
 * <li>If the {@code targetUrlParameter} has been set on the request, the value will be
 * used as the destination. Any {@code DefaultSavedRequest} will again be removed.</li>
 * <li>If a {@link org.springframework.security.web.savedrequest.SavedRequest} is found in
 * the {@code RequestCache} (as set by the {@link ExceptionTranslationFilter} to record
 * the original destination before the authentication process commenced), a redirect will
 * be performed to the Url of that original destination. The {@code SavedRequest} object
 * will remain cached and be picked up when the redirected request is received (See
 * <a href="
 * {@docRoot}/org/springframework/security/web/savedrequest/SavedRequestAwareWrapper.html">SavedRequestAwareWrapper</a>).
 * </li>
 * <li>If no {@link org.springframework.security.web.savedrequest.SavedRequest} is found,
 * it will delegate to the base class.</li>
 * </ul>
 *
 * @author Luke Taylor
 * @since 3.0
 */
public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    protected final Log logger = LogFactory.getLog(this.getClass());

    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
          Authentication authentication) throws ServletException, IOException {
       SavedRequest savedRequest = this.requestCache.getRequest(request, response);
       if (savedRequest == null) {
          super.onAuthenticationSuccess(request, response, authentication);
          return;
       }
       String targetUrlParameter = getTargetUrlParameter();
       if (isAlwaysUseDefaultTargetUrl()
             || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
          this.requestCache.removeRequest(request, response);
          super.onAuthenticationSuccess(request, response, authentication);
          return;
       }
       clearAuthenticationAttributes(request);
       // Use the DefaultSavedRequest URL
       String targetUrl = savedRequest.getRedirectUrl();
       getRedirectStrategy().sendRedirect(request, response, targetUrl);
    }

    public void setRequestCache(RequestCache requestCache) {
       this.requestCache = requestCache;
    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-05-31,如有侵权请联系 cloudcommunity@tencent 删除对象日志源码分析重定向request