记住我和身份验证成功处理程序

Jig*_*ekh 11 spring spring-security

我有登录成功和重定向到页面的奇怪问题.

下面是我的弹簧安全配置.

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/login.hst**" access="anonymous or authenticated" />
    <intercept-url pattern="/**/*.hst" access="authenticated" />
    <form-login login-page="/login.hst"
        authentication-failure-url="/login.hst?error=true"
        authentication-success-handler-ref="loginSucessHandler" />
    <logout invalidate-session="true" logout-success-url="/home.hst"
        logout-url="/logout.hst" />
    <remember-me key="jbcpHaverERP" authentication-success-handler-ref="loginSucessHandler"/>
    <session-management>
    <concurrency-control max-sessions="1" />
</session-management>
</http>
Run Code Online (Sandbox Code Playgroud)

LoginSuessHandler类:

@Service
public class LoginSucessHandler extends
        SavedRequestAwareAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {
            ...
        super.setUseReferer(true);
        super.onAuthenticationSuccess(request, response, authentication);
    }

}
Run Code Online (Sandbox Code Playgroud)

现在成功重定向到请求页面的问题.如果我直接引用任何安全网址spring将我重定向到登录页面并成功登录到原始请求的链接.但是,如果用户之前选择了remember-me然后关闭浏览器并且现在请求直接URL,那么这不起作用,他正在进行适当的身份验证,而不是将他重定向到请求的页面重定向到/.我检查了日志和一些弹簧源代码,发现它无法确定目标网址.

我试图设置引用但引用值为null.但有一件奇怪的事我注意到,在spring安全配置中,如果我从remember-me配置中删除authentication-success-handler,那么它可以工作.

    <remember-me key="jbcpHaverERP" authentication-success-handler-ref="loginSucessHandler"/>
Run Code Online (Sandbox Code Playgroud)

无法弄清楚问题.是身份验证成功处理程序实现需要不同的表单登录和记住我吗?

Sha*_*eep 14

记住我与表单登录的不同之处在于,在用户提出的实际请求期间进行身份验证.对于表单登录,必须首先将用户重定向到登录页面,提交登录表单,然后将其重定向到原始目标(通常在会话中缓存).因此,表单登录需要重定向,而记住我不需要.通过记住我的请求,可以对用户进行身份验证,并允许请求继续进行而无需任何干预.

一个主要目的AuthenticationSuccessHandler是在身份验证后控制导航流程,因此您通常不会使用一个记住我的导航流程.使用SavedRequestAwareAuthenticationSuccessHandler不是一个好主意,因为没有可用的保存请求.如果没有已保存的请求,则默认情况下它将执行重定向到"/",如您所观察到的那样.

如果您只想在记住我的登录过程中添加一些功能,那么您可以AuthenticationSuccessHandler直接实现该界面而无需执行重定向或转发.如上所述,您不能对表单登录使用相同的实现,因为当前请求是提交登录表单(通常是URL j_spring_security_check),而不是对应用程序中的URL的请求.因此,您需要重定向表单登录.

  • 你想要的是不可能的,因为如果你提供successHandler,过滤器将返回并且不调用chain.doFilter(request,response); 尝试使用AuthenticationApplicationListener作为kabak提及. (2认同)

kab*_*bal 13

您宁愿使用ApplicationListener并寻找活动InteractiveAuthenticationSuccessEvent.

InteractiveAuthenticationSuccessEvent有一个属性generatedBy,将是过滤器,即UsernamePasswordAuthenticationFilter(形式登录)和RememberMeAuthenticationFilter(记住我登录)

@Component
class AuthenticationApplicationListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {

  @Override
  void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
    //do something
  }

}
Run Code Online (Sandbox Code Playgroud)

AuthenticationSuccessHandler在rememberMe上使用自定义实现会导致问题.看一下流程RememberMeAuthenticationFilter.如果successHandler使用,则绕过滤波器链