使用 Spring Security 成功登录后如何将用户转发回所需的受保护页面

Posted

技术标签:

【中文标题】使用 Spring Security 成功登录后如何将用户转发回所需的受保护页面【英文标题】:How to forward User back to desired protected page after successful login with Spring Security 【发布时间】:2013-01-25 08:08:58 【问题描述】:

我正在使用 Spring Security 来处理我的 Web 应用程序的所有身份验证。情况如下,假设我有三个 JSP 页面:

1) 登录页面 2) 默认主页(需要认证) 3) 用户账号页面(需要认证)

标准流程可以正常工作:

1) 用户从登录页面成功登录 2) 用户被带到默认主页

这是我想不通的用例

1) 用户尝试访问他们的帐户页面(但受密码保护) - 有效 2) 用户被重定向以输入他们的凭据 - 有效 3) 用户成功提供凭据 - 有效 4) 用户被重定向到他们的帐户页面 - 不起作用(它将他们重定向到默认主页)

我使用的是自定义 AuthenticationSuccessHandler,但问题是,每当我查看请求以查看它们来自哪里时,它总是来自 /j_spring_security_check

有没有一些简单的方法来隔离它们来自哪个页面?

这是我的 applicationContext.xml 中与我的 Spring Security 设置相关的内容:

<bean id="successfulLoginService" class="com.service.SuccessfulLoginService">
    <property name="defaultTargetUrl" value="/listings/add_listing.htm"/>
  </bean>

  <security:http pattern="/**.html" security="none" />
  <security:http pattern="/login/*.htm" security="none" />
  <security:http pattern="/listings/listing.htm" security="none" />
  <security:http pattern="/listings/viewListing.htm" security="none" />
  <security:http pattern="/search/keyword/*.htm" security="none" />

  <security:http auto-config="true">
    <security:intercept-url pattern="/**.htm" access="ROLE_USER" />
    <security:intercept-url pattern="/**/**.htm" access="ROLE_USER" />
    <security:form-login login-page="/login/login.htm" authentication-failure-handler-ref="failedLoginService" authentication-success-handler-ref="successfulLoginService"/>
  </security:http>

  <security:authentication-manager>
    <security:authentication-provider
      user-service-ref="userDetailsService" />
  </security:authentication-manager>

这是我的 SuccessLoginService.java:

@Service("successfulLoginService")
public class SuccessfulLoginService extends SimpleUrlAuthenticationSuccessHandler

  @Autowired
  UserDao userDao;

  @Override
  public void onAuthenticationSuccess(HttpServletRequest request,
      HttpServletResponse response, Authentication authentication)
      throws IOException, ServletException
  
    Users user = null;
    String username = ((SpringSecurityUser) authentication.getPrincipal()).getUsername();
    try
    
      user = userDao.getUserByEmail(username);
     catch (Exception e)
    
      e.printStackTrace();
      throw new ServletException("Failed to login", e);
    
    request.getSession().setAttribute("user", user);

    response.sendRedirect("/MyApplication" + determineTargetUrl(request, response));
  

【问题讨论】:

【参考方案1】:

您在寻找default-target-url 吗?您可以使用它在成功登录后将用户重定向到某个位置。

【讨论】:

我不相信,我只是尝试插入它,但没有奏效。我也在使用 authentication-success-handler-ref ,这可能会导致代码混乱。我尝试在我的 authentication-success-handler-ref 中连接一个 default-target-url,但它总是导航到那个 URL(即使那不是我一开始没有访问权限时尝试访问的那个) 【参考方案2】:

您可以从org.springframework.security.web.savedrequest.RequestCache获取保存的请求。

在您的自定义成功处理程序内部:

RequestCache requestCache = new HttpSessionRequestCache();
SavedRequest savedRequest = requestCache.getRequest(request, response);
String targetUrl = savedRequest.getRedirectUrl();

查看默认SavedRequestAwareAuthenticationSuccessHandler 了解更多详情。

【讨论】:

我不知道为什么我以前不知道该怎么做。几个月来我一直在寻找这个答案,当我无法弄清楚时,我一直把它放在次要位置。非常感谢您花时间回答我的问题 Aleksandr,你是我本周的英雄。

以上是关于使用 Spring Security 成功登录后如何将用户转发回所需的受保护页面的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Security 成功登录后如何正确更新登录日期时间?

使用 Spring Security 监听成功登录

使用 Spring Security 处理成功的登录事件

使用spring security成功登录后如何将对象添加到视图中?

spring security为不同用户显示各自的登录成功页面

Spring Security6登录用户退出登录操作