在Spring 3.1中使用remember-me功能登录用户

at.*_*at. 17 security spring spring-mvc spring-security remember-me

我目前以编程方式(例如,当他们通过Facebook或其他方式登录而不是使用我的登录表单)登录用户时:

SecurityContextHolder.getContext().setAuthentication(
  new UsernamePasswordAuthenticationToken(user, "", authorities)
);
Run Code Online (Sandbox Code Playgroud)

我想要做的是将用户登录,就好像他们在登录表单中设置了remember-me选项一样.所以我猜我需要使用RememberMeAuthenticationToken而不是UsernamePasswordAuthenticationToken?但是,我为key构造函数的参数添加了什么?

RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) 
Run Code Online (Sandbox Code Playgroud)

更新:我正在使用此处描述持久令牌方法.因此,基于简单哈希的令牌方法中没有关键字.

sou*_*ica 14

我假设您已经<remember-me>设置了配置.

记住我工作的方式是设置一个cookie,当用户在会话过期后返回到站点时识别该cookie.

您必须子类化您正在使用的RememberMeServices(TokenBasedPersistentTokenBased)并使onLoginSuccess()公开.例如:

public class MyTokenBasedRememberMeServices extends PersistentTokenBasedRememberMeServices {
    @Override
    public void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
        super.onLoginSuccess(request, response, successfulAuthentication);
    }   
} 

<remember-me services-ref="rememberMeServices"/>

<bean id="rememberMeServices" class="foo.MyTokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <!-- etc -->
</bean>
Run Code Online (Sandbox Code Playgroud)

将RememberMeServices注入您正在进行程序化登录的bean中.然后onLoginSuccess()使用您创建的UsernamePasswordAuthenticationToken 调用它.这将设置cookie.

UsernamePasswordAuthenticationToken auth = 
    new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);
getRememberMeServices().onLoginSuccess(request, response, auth);  
Run Code Online (Sandbox Code Playgroud)

UPDATE

@at改进了这个,没有子类化 RememberMeServices:

UsernamePasswordAuthenticationToken auth = 
    new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);

// This wrapper is important, it causes the RememberMeService to see
// "true" for the "_spring_security_remember_me" parameter.
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) {
    @Override public String getParameter(String name) { return "true"; }            
};

getRememberMeServices().loginSuccess(wrapper, response, auth);  
Run Code Online (Sandbox Code Playgroud)