在Spring 3.1中使用“记住我”功能登录用户
目前,我通过以下方式以编程方式登录用户(如通过Facebook或其他方式登录,而不是使用我的登录表单): 我想做的是让用户登录,就像他们在登录表单中设置了“记住我”选项一样。所以我猜我需要使用在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
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);