Java 为春季社交活动实施“记住我”计划
我有一个支持spring安全性的项目。我已经使用登录表单实现了一个RememberMe,它运行良好。但我也有来自谷歌/facebook的社交登录,效果很好。问题是他们不记得用户。有没有办法设置类似的“记住我”功能 正常登录页面的当前spring配置:Java 为春季社交活动实施“记住我”计划,java,spring-security,spring-social,Java,Spring Security,Spring Social,我有一个支持spring安全性的项目。我已经使用登录表单实现了一个RememberMe,它运行良好。但我也有来自谷歌/facebook的社交登录,效果很好。问题是他们不记得用户。有没有办法设置类似的“记住我”功能 正常登录页面的当前spring配置: <http access-denied-page="/login?authorization_error=true" disable-url-rewriting="true" authentication-manager-re
<http access-denied-page="/login?authorization_error=true"
disable-url-rewriting="true" authentication-manager-ref="formAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/account/**" access="ROLE_USER" />
<remember-me key="iRemember"
token-validity-seconds="1209600" user-service-ref="formClientDetailsUserService" />
<form-login authentication-failure-url="/login?authentication_error=true"
default-target-url="/account/" login-page="/login"
login-processing-url="/login.do" />
<logout logout-success-url="http://example.com" logout-url="/logout" />
<anonymous />
</http>
我有一些类似的要求 我尝试将用于身份验证的url设置为
/auth/facebook?\u spring\u security\u memory\u me=true
(请参阅AbstractMemberServices.MemberRequested
)。但是,我不会放过这一切。它的编码如下:
protected boolean detectRejection(HttpServletRequest request) {
Set<?> parameterKeys = request.getParameterMap().keySet();
return parameterKeys.size() > 0
&& !parameterKeys.contains("oauth_token")
&& !parameterKeys.contains("code")
&& !parameterKeys.contains("scope");
}
下面是我将
RememberMeServices
与springsocial
集成所做的工作。正如@Sanjay所说,它基于AlwaysRemember=true
逻辑
与默认的TokenBasedMemberMeservices
不同,我们定制了一点:
public class DynamicRememberMeServices extends TokenBasedRememberMeServices {
public final static String PARAM_BASED_KEY = "remember-me-param-based";
public final static String REMEMBER_ME_KEY = "remember-me";
private Logger logger = LoggerFactory.getLogger(getClass());
public DynamicRememberMeServices(String key, UserDetailsService userDetailsService){
super(key, userDetailsService);
super.setParameter(REMEMBER_ME_KEY);
super.setCookieName(REMEMBER_ME_KEY);
}
@Override
protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
if("on".equalsIgnoreCase(request.getParameter(PARAM_BASED_KEY)) ){
logger.debug("param based request");
return super.rememberMeRequested(request, parameter);
}
logger.debug("always remember me");
return true;
}
}
在login.html
上:
<form th:action="@{/login}" method="post">
User Name : <input type="text" name="username"/>
Password: <input type="password" name="password"/>
<input type="hidden" name="remember-me-param-based" value="on" />
Remember me: <input type='checkbox' name='remember-me' checked="checked"/>
<input type="hidden" name="_csrf" th:value="${_csrf.token}"/>
<input type="submit" value="Sign In"/>
</form>
<a th:href="@{/auth/facebook}">Or via facebook</a>
用户名:
密码:
记住我:
因此,在facebook登录(通过/auth/facebook
)的情况下,它将通过返回true
来使用AlwaysMemberMe
策略,但对于传统的表单登录
,这取决于:
- 如果请求正文中的
,它将根据给定参数(记住我参数based=on
)检查continue as traditional记住我
)TokenbasedMemberMeservices
- 如果缺少
,它将始终作为基于memory me param的
工作memberme
IMHO我的实现至少为“传统登录”用户提供了选择。我们切换到Java配置并创建了记住我的服务:
@Bean
public MyRememberMeServices myRememberMeServices(){
MyRememberMeServices service = new MyRememberMeServices (REMEMBERME_KEY, formUserDetailsService);
service.setAlwaysRemember(true);
service.setCookieName("xxxx");
service.setParameter("_spring_security_remember_me");
service.setTokenValiditySeconds(123);
return service;
};
然后在社交登录的SignInAdapter实现上:
@Override
public String signIn(String userId, Connection<?> connection, NativeWebRequest request) {
// load the user based on the account id
// create an authentication object to store in context
// set remember-me cookie
myRememberMeServices.onLoginSuccess(
(HttpServletRequest) request.getNativeRequest(),
(HttpServletResponse) request.getNativeResponse(),
authentication);
// forward to the original URL
return extractOriginalUrl(request);
}
@覆盖
公共字符串签名(字符串用户ID、连接、NativeWebRequest请求){
//根据帐户id加载用户
//创建要存储在上下文中的身份验证对象
//请记住我的曲奇
MyMemberServices.onLoginSAccess(
(HttpServletRequest)请求。getNativeRequest(),
(HttpServletResponse)请求。getNativeResponse(),
认证);
//转发到原始URL
返回提取器originalurl(请求);
}
为了回答这个问题,按照最初的提问方式(使用XML配置),Spring Security 3.2+支持memory me元素上的services ref属性。因此,在您的安全配置中,您将有:
<security:http xmlns="http://www.springframework.org/schema/security">
...
<remember-me services-ref="rememberMeServices" key="secret-key">
</security:http>
<bean id="rememberMeServices" class="com.example.MyRememberMeServices">
<constructor-arg index="0" value="secret-key" />
<constructor-arg index="1" ref="userDetailsService" />
<property name="tokenValiditySeconds" value="1000000" />
</bean>
...
其中MyMemberServices可以是checklist的版本,也可以是beku8的DynamicMemberServices。我更喜欢beku8的版本,因为它为正常登录留下了启用“记住我”的选择。我对始终使用“记住我”感兴趣,并且我添加了setAlwaysRemember(true)。但春天似乎忽视了这一点。那么,我如何将MemberMeServices与社交网站联系起来呢?MemberMeServices.setAlwaysRemember(true),正如我所记得的那样,上面的设置对我有效。我尝试了你的方法,但仍然无法将MemberMe服务与社交登录网站联系起来。有这样的设置吗?您使用的是
SocialAuthenticationFilter
而不是ProviderSignInController
对吗?如果是这样,您只需以常规方式注入它,如http.rememberMeServices(rememberMeServices())
@beku8您能否提供一个使用SocialAuthenticationFilter时使用http.rememberMeServices(rememberMeServices())的示例?将您的方法与beku8的版本相结合。没用
<security:http xmlns="http://www.springframework.org/schema/security">
...
<remember-me services-ref="rememberMeServices" key="secret-key">
</security:http>
<bean id="rememberMeServices" class="com.example.MyRememberMeServices">
<constructor-arg index="0" value="secret-key" />
<constructor-arg index="1" ref="userDetailsService" />
<property name="tokenValiditySeconds" value="1000000" />
</bean>