Java 没有以编程方式登录时创建的Spring安全记住我cookie

Java 没有以编程方式登录时创建的Spring安全记住我cookie,java,spring,spring-boot,spring-security,spring-social,Java,Spring,Spring Boot,Spring Security,Spring Social,注册(注册)后,我立即通过Spring Security以编程方式登录我的用户: public register(HttpServletRequest request, String user, String password) { ... request.login(user, password); } 这可以正常工作,但不会创建“记住我”cookie(尽管通过交互式登录,cookie可以正常创建)。 现在我已经阅读并回答了,您必须连接RememberMeServices(我

注册(注册)后,我立即通过Spring Security以编程方式登录我的用户:

public register(HttpServletRequest request, String user, String password) {
    ...
    request.login(user, password);
}
这可以正常工作,但不会创建“记住我”cookie(尽管通过交互式登录,cookie可以正常创建)。

现在我已经阅读并回答了,您必须连接
RememberMeServices
(我使用
persistentTokenbasedMembermeservices
)的实现,然后调用
onloginsAccess
。我尚未成功自动连接到PersistentTokenBasedMemberMeservices


如何做到这一点?这条路对吗?为什么SpringSecurity没有提供更方便的方法


备注:这是我的配置的摘录:

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .tokenRepository(new MyPersistentTokenRepository())
                .rememberMeCookieName("rememberme")
                .tokenValiditySeconds(60 * 60 * 24) 
                .alwaysRemember(true)
                .useSecureCookie(true)
                .and()
            ....
       ...
    }
}

你没有提到春季版。下面的配置将与Spring4一起使用,但您可以为其他版本修改它。在您的
WebSECONF
class autowire
PersistentTokenRepository
UserDetailsService
界面中。添加Bean以获取
persistentTokenBasedMemberMeservices
实例

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

@Autowired
PersistentTokenRepository persistenceTokenRepository;
@Autowired
UserDetailsService userDetailsService;
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .tokenRepository(persistenceTokenRepository)
                .rememberMeCookieName("rememberme")
                .tokenValiditySeconds(60 * 60 * 24) 
                .alwaysRemember(true)
                .useSecureCookie(true)
                .and()
            ....
       ...
    }

@Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
    PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new PersistentTokenBasedRememberMeServices("rememberme", userDetailsService, persistenceTokenRepository);
    persistenceTokenBasedservice.setAlwaysRemember(true);
    return persistenceTokenBasedservice;
  }
}
现在,在您正在进行编程登录的控制器或类中,autowire
PersistentTokenBasedMemberMeservices
并在方法中添加以下代码以调用
LoginsAccess
方法

@Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null){
        persistentTokenBasedRememberMeServices.loginSuccess(request, response, auth);
    }

你没有提到春季版。下面的配置将与Spring4一起使用,但您可以为其他版本修改它。在您的
WebSECONF
class autowire
PersistentTokenRepository
UserDetailsService
界面中。添加Bean以获取
persistentTokenBasedMemberMeservices
实例

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

@Autowired
PersistentTokenRepository persistenceTokenRepository;
@Autowired
UserDetailsService userDetailsService;
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .tokenRepository(persistenceTokenRepository)
                .rememberMeCookieName("rememberme")
                .tokenValiditySeconds(60 * 60 * 24) 
                .alwaysRemember(true)
                .useSecureCookie(true)
                .and()
            ....
       ...
    }

@Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
    PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new PersistentTokenBasedRememberMeServices("rememberme", userDetailsService, persistenceTokenRepository);
    persistenceTokenBasedservice.setAlwaysRemember(true);
    return persistenceTokenBasedservice;
  }
}
现在,在您正在进行编程登录的控制器或类中,autowire
PersistentTokenBasedMemberMeservices
并在方法中添加以下代码以调用
LoginsAccess
方法

@Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null){
        persistentTokenBasedRememberMeServices.loginSuccess(request, response, auth);
    }

我无意中发现了这个问题,并努力让一切正常运行,这是如何设置的,以供将来参考

定义一个根据您的需要配置的
rememberservice
bean

如果您想要一个简单的基于哈希的令牌系统,请使用
TokenBasedRememberMeServices
,如果您想要将令牌持久化到数据库,请使用
PersistentTokenBasedRememberMeServices
。这两种解决方案将在此处详细介绍:

请注意,构造函数的第一个参数不是cookie名称,而是用于验证RememberMe令牌的密钥

@Configuration
public class SecurityBeans {
    @Autowire
    PersistentTokenRepository persistenceTokenRepository;
    @Autowired
    UserDetailsService userDetailsService;


    @Bean
    public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
        PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new TokenBasedRememberMeServices("remember-me-key", userDetailsService, persistenceTokenRepository);
        persistenceTokenBasedservice.setCookieName("rememberme");
        persistenceTokenBasedservice.setTokenValiditySeconds(60 * 60 * 24);
        persistenceTokenBasedservice.setAlwaysRemember(true);
        persistenceTokenBasedservice.setUseSecureCookie(true);
        return persistenceTokenBasedservice;
    }
}
配置
HttpSecurity
时,应直接注入
rememberservice
。您还必须配置与
rememberservice
中定义的密钥完全相同的密钥,因为配置者还设置了
rememberauthenticationprovider
,该提供者检查
rememberservice
生成的memberme令牌密钥是否正确

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

    @Autowired
    RememberMeServices rememberMeServices;
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .rememberMeServices(rememberMeServices)
                .key("remember-me-key")
                .and()
            ....
       ...
    }
}

最后,您应该在编程登录的方法中调用
RememberMeService
loginsucess

我无意中发现了这个问题,并努力使一切正常工作,这是如何设置的,以供将来参考

定义一个根据您的需要配置的
rememberservice
bean

如果您想要一个简单的基于哈希的令牌系统,请使用
TokenBasedRememberMeServices
,如果您想要将令牌持久化到数据库,请使用
PersistentTokenBasedRememberMeServices
。这两种解决方案将在此处详细介绍:

请注意,构造函数的第一个参数不是cookie名称,而是用于验证RememberMe令牌的密钥

@Configuration
public class SecurityBeans {
    @Autowire
    PersistentTokenRepository persistenceTokenRepository;
    @Autowired
    UserDetailsService userDetailsService;


    @Bean
    public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
        PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new TokenBasedRememberMeServices("remember-me-key", userDetailsService, persistenceTokenRepository);
        persistenceTokenBasedservice.setCookieName("rememberme");
        persistenceTokenBasedservice.setTokenValiditySeconds(60 * 60 * 24);
        persistenceTokenBasedservice.setAlwaysRemember(true);
        persistenceTokenBasedservice.setUseSecureCookie(true);
        return persistenceTokenBasedservice;
    }
}
配置
HttpSecurity
时,应直接注入
rememberservice
。您还必须配置与
rememberservice
中定义的密钥完全相同的密钥,因为配置者还设置了
rememberauthenticationprovider
,该提供者检查
rememberservice
生成的memberme令牌密钥是否正确

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

    @Autowired
    RememberMeServices rememberMeServices;
    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .rememberMeServices(rememberMeServices)
                .key("remember-me-key")
                .and()
            ....
       ...
    }
}

最后,您应该在进行编程登录的方法中调用
rememberservice
loginsucess

谢谢您的回答!我认为,这可能是一个好办法。唯一的问题是,
persistentTokenBasedMemberMeservices
没有连接-调用
persistentTokenBasedMemberMeservices.loginsAccess(请求、响应、身份验证)
P.S.:我使用Spring 4。一旦定义“@Bean”对于我发布的WebSECONF类中的PersistentTokenBasedMemberMeservices,当您在Controller中自动连接它时,它不应为null。好的-我现在明白了:它必须自动连接到Spring管理的组件中-到对象中,它是由
new
构建的,不会连接。此解决方案是否持久化TokenBasedMemberMeservices作为全局类属性)线程安全?还是会有未定义的效果,当它将被多个用户使用?谢谢你的回答!我认为,这可能是一个好办法。唯一的问题是,
persistentTokenBasedMemberMeservices
没有连接-调用
persistentTokenBasedMemberMeservices.loginsAccess(请求、响应、身份验证)
P.S.:我使用Spring 4。一旦定义“@Bean”对于我发布的WebSECONF类中的PersistentTokenBasedMemberMeservices,当您在Controller中自动连接它时,它不应为null。好的-我现在明白了:它必须自动连接到Spring管理的组件中-到对象中,它是由
new
构建的,不会连接。此解决方案是否持久化TokenBasedMemberMeservices作为全局类属性)线程安全?或者当多个用户使用它时,会有未定义的效果吗?