【问题标题】:Spring security removes all remember me tokensSpring security 删除所有记住我的令牌
【发布时间】:2017-07-10 13:47:15
【问题描述】:

我已经在我的网络服务中实现了记住我的功能,但问题是当我基于 tomcat 重新启动服务器时,服务器会从 persistent_logins 表中删除所有记录。这是我的 servlet 配置文件:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd">

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

<context:component-scan base-package="com.bitcointech.*" />

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/pages/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<bean
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    id="entityManagerFactory">
    <property name="packagesToScan" value="com.bitcointech.entities" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.databasePlatform">
            org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
    <property name="persistenceProvider">
        <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
    </property>
</bean>

<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/"  
cache-period="31556926"/>
<mvc:annotation-driven />

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
id="transactionManager">
  <property name="dataSource" ref="dataSource" />
</bean>

<jpa:repositories base-package="com.bitcointech.repositories" 
entity-manager-factory-ref="entityManagerFactory">
</jpa:repositories>

Spring 安全文件:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/admin**" access="hasRole('ROLE_USER')" />
    <intercept-url pattern="/advance**" access="hasRole('ROLE_USER')" />
    <intercept-url pattern="/changeState**" access="hasRole('ROLE_USER')"/>
    <intercept-url pattern="/history**" access="hasRole('ROLE_USER')"/>
    <form-login
        login-page="/login"
        default-target-url="/admin"
        authentication-failure-url="/login?error"
        username-parameter="token"
        password-parameter="password" />
    <logout logout-success-url="/admin" />
    <csrf/>
    <session-management>
        <concurrency-control max-sessions="10" session-registry-alias="sessionRegistry" />
    </session-management>
    <remember-me token-validity-seconds="31536000" 
        remember-me-parameter="remember-me" 
        data-source-ref="dataSource" />
</http>

<authentication-manager>
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query=
                "select token, password, enabled from users where token = ?"
            authorities-by-username-query=
                "select token, role from user_roles where token = ?" />
    </authentication-provider>
</authentication-manager>

任何想法如何改变它?

【问题讨论】:

    标签: java spring security remember-me


    【解决方案1】:

    如果要将 cookie 持久化到数据库,则需要添加额外的 bean。修改您的安全配置如下:

    <beans:bean id="rememberMeAuthenticationProvider" 
    class="org.springframework.security.web.
                authentication.rememberme.PersistentTokenBasedRememberMeServices">
        <beans:constructor-arg value="myAppKey" />
        <beans:constructor-arg ref="jdbcTokenRepository" />
        <beans:constructor-arg ref="UserDetailsService" />
    </beans:bean>
    
    <beans:bean id="jdbcTokenRepository"
      class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"> 
        <beans:property name="createTableOnStartup" value="false" /> 
        <beans:property name="dataSource" ref="dataSource" /> 
    </beans:bean>
    
    <authentication-manager alias="authenticationManager"> 
        <authentication-provider user-service-ref="UserDetailsService"/> 
        </authentication-provider> 
    </authentication-manager>
    

    【讨论】:

    • 好吧,它似乎工作,但我有一个例外:“org.springframework.beans.factory.parsing.BeanDefinitionParsingException:配置问题:用户服务引用属性不能用于与子元素 'user-service'、'jdbc-user-service' 或 'ldap-user-service' 组合”
    【解决方案2】:

    目前,我已将所有内容从 xml 移动到 java,我的配置如下所示:

    @EnableWebSecurity
    @Configuration
    public class WebSecurity extends WebSecurityConfigurerAdapter
    {
            @Override
            protected void configure(HttpSecurity http) throws Exception 
            {
                http
                .authorizeRequests()
                .antMatchers("/admin**").access("hasRole('ROLE_USER')")
                .antMatchers("/advance**").access("hasRole('ROLE_USER')")
                .antMatchers("/changeState**").access("hasRole('ROLE_USER')")
                .antMatchers("/history**").access("hasRole('ROLE_USER')")
                .and()
                .formLogin().loginPage("/login").loginProcessingUrl("/j_spring_security_check")
                .defaultSuccessUrl("/admin")
                .failureUrl("/login?error")
                .usernameParameter("token")
                .passwordParameter("password")
                .and()
                .logout().logoutSuccessUrl("/admin").deleteCookies("JSESSIONID")
                .and().headers().frameOptions().sameOrigin().and().csrf()
                .and().rememberMe().tokenValiditySeconds(31536000)
                .rememberMeParameter("remember-me").rememberMeCookieName("remember-me")
                .tokenRepository(persistentTokenRepository())
                .and().sessionManagement().maximumSessions(10000).sessionRegistry(getSessionRegistry());       
            }
    
            @Bean
            public PersistentTokenRepository persistentTokenRepository() 
            {
                JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
                db.setDataSource(dataSource());
                return db;
            } 
    
            @Bean(name = "hibernatePersistenceProvider")
            public HibernatePersistenceProvider hibernatePersistenceProvider() 
            {
                return new HibernatePersistenceProvider();
            }
    
            @Bean(name = "dataSource")
            public DriverManagerDataSource dataSource() 
            {
                DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
                driverManagerDataSource.setDriverClassName("org.postgresql.Driver");
                driverManagerDataSource.setUrl("jdbc:postgresql://localhost:5432/arbitraz");
                driverManagerDataSource.setUsername("postgres");
                driverManagerDataSource.setPassword("alan12");
                return driverManagerDataSource;
            }
    
            @Bean(name = "savedRequestAwareAuthenticationSuccessHandler")
            public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler() 
            {
                SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
                handler.setTargetUrlParameter("targetUrl");
                return handler;
            }
    
            @Bean(name = "entityManagerFactory")
            public LocalContainerEntityManagerFactoryBean emf() 
            {
                LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
                bean.setPackagesToScan("com.bitcointech.entities");
                bean.setDataSource(dataSource());
                Properties prop = new Properties();
                prop.put("hibernate.databasePlatform", "org.hibernate.dialect.PostgreSQLDialect");
                prop.put("hibernate.show_sql", false);
                prop.put("hibernate.hbm2ddl.auto", "update");
                bean.setJpaProperties(prop);
                bean.setPersistenceProvider(hibernatePersistenceProvider());
                return bean;
            }
    
            @Autowired
            public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
            {
                auth.jdbcAuthentication().dataSource(dataSource())
                        .usersByUsernameQuery(
                                "select token, password, enabled from users where token = ?")
                        .authoritiesByUsernameQuery("select token, role from user_roles where token = ?");
            }
    
            @Bean
            public SessionRegistry getSessionRegistry() 
            {
                return new SessionRegistryImpl();
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-09-23
      • 2015-05-10
      • 2012-01-21
      • 2018-12-02
      • 1970-01-01
      • 2014-09-04
      • 2012-03-13
      • 1970-01-01
      • 2012-04-20
      相关资源
      最近更新 更多