Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Spring 3.1中使用“记住我”功能登录用户_Spring_Spring Mvc_Spring Security_Security_Remember Me - Fatal编程技术网

在Spring 3.1中使用“记住我”功能登录用户

在Spring 3.1中使用“记住我”功能登录用户,spring,spring-mvc,spring-security,security,remember-me,Spring,Spring Mvc,Spring Security,Security,Remember Me,目前,我通过以下方式以编程方式登录用户(如通过Facebook或其他方式登录,而不是使用我的登录表单): 我想做的是让用户登录,就像他们在登录表单中设置了“记住我”选项一样。所以我猜我需要使用rememberAuthenticationToken而不是UsernamePasswordAuthenticationToken?但是对于构造函数的键参数,我该怎么做呢 RememberMeAuthenticationToken(String key, Object principal, Collecti

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

我想做的是让用户登录,就像他们在登录表单中设置了“记住我”选项一样。所以我猜我需要使用
rememberAuthenticationToken
而不是
UsernamePasswordAuthenticationToken
?但是对于构造函数的
参数,我该怎么做呢

RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) 

RememberMeAuthenticationToken(字符串键、对象主体、集合这是构造函数的源代码

public RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) {
    super(authorities);

    if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal)) {
        throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
    }

    this.keyHash = key.hashCode();
    this.principal = principal;
    setAuthenticated(true);
}

因此,要回答您的问题,您需要传递表示用户的
身份验证
字段的
键的散列码
我假设您已经在配置中设置了

“记住我”的工作方式是,它设置了一个cookie,当用户会话过期后返回站点时,该cookie会被识别

您必须对正在使用的
RememberMeServices
TokenBased
PersistentTokenBased
)进行子类化,并将onloginsAccess()公开。例如:

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>
更新

@在此基础上进行了改进,没有
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);  

你的意思是你只想在SecurityContextHolder中设置身份验证?还是你也需要设置“记住我”cookie?我想让该用户登录,我的应用程序会记住他们,这样他们就不必再次登录。我仍然不知道该怎么办。我如何获得代表该用户的
身份验证
。然后我该怎么办作为关键参数传递?在我的安全XML配置中,我只是在
元素中有
。在哪里定义了
TokenBasedMemberMeservices
bean?使用这种机制,我不需要再与SecurityContextHolder为伍了吗?听起来是一个更好的解决方案,可以通过编程方式登录我假设我需要的是
persistentTokenBasedMemberMeservices
而不是
TokenBasedMemberMeservices
。但是不管怎样,如果我可以将它注入到我试图使用“记住我”功能登录某人的控制器中,
loginsAccess()
似乎不是我想要的。Javadocs说,检查传入请求并检查是否存在已配置的“记住我”参数。如果存在该参数,或者如果alwaysRemember设置为true,则仅调用LoginSAccess。“您使用的是哪个版本的Spring Security?我指的是3.0版的org.springframework.Security.web.authentication.rememberme.tokenbasedrembermeservices。您可以对
tokenbasedrembermeservices
的持久版本或常规版本执行此操作。我刚刚检查了3.1源代码(抱歉,我错过了此代码)。”这是一样的。不需要扩展类或使用包装器。只需在PersistentTokenBasedMemberMeservices上设置alwaysRemember=true。不幸的是,这似乎无法通过XML元素完成,因此您需要定义bean PersistentTokenBasedMemberMeservices并将该属性设置为true。在正常的RememberServices.LoginsAccess之后(req、res、auth)创建cookie和持久记录
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>
UsernamePasswordAuthenticationToken auth = 
    new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);
getRememberMeServices().onLoginSuccess(request, response, auth);  
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);