Spring 安全记住我 Ajax 登录

Spring Security Remember-me with Ajax login

我已经实施 spring 安全 ajax 登录。 .

我定义了自己的 customAuthenticationEntryPointauthenticationFiltersecurityLoginSuccessHandler。它可以成功验证用户。但是,当我添加记住我的部分时。这是行不通的。数据库中没有SQL运行插入token到persistent_logins。不知道是不是我的配置有问题?请帮忙。

<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"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
    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://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <http pattern="/resources/**" security="none" />
    <http auto-config="false" use-expressions="true" entry-point-ref="customAuthenticationEntryPoint">

        <intercept-url pattern="/**" access="permitAll" />

        <access-denied-handler error-page="/denied" />

        <logout invalidate-session="true" delete-cookies="JSESSIONID"
            success-handler-ref="securityLogoutSuccessHandler" logout-url="/logout" />

        <custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER" />
        <csrf />

        <!-- enable remember me -->
    <remember-me 
        services-ref = "rememberMeServices"
        key = "_spring_security_remember_me" />
    </http>


    <beans:bean id="rememberMeServices"
                class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
        <beans:property name="key" value="_spring_security_remember_me"/>
        <beans:property name="alwaysRemember" value="true"/>
        <beans:property name="tokenRepository" ref="jdbcTokenRepository"/>
        <beans:property name="userDetailsService" 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>

    <beans:bean id="customAuthenticationEntryPoint"
        class="com.tong.beau.service.security.CustomAuthenticationEntryPoint">
        <beans:property name="loginPageUrl" value="/login" />
        <beans:property name="returnParameterEnabled" value="true" />
        <beans:property name="returnParameterName" value="r" />
    </beans:bean>

    <beans:bean id="authenticationFilter"
        class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager" />
        <beans:property name="filterProcessesUrl" value="/security_check" /><!-- 
            change here if customize form action -->
        <!-- handler are for login with ajax POST -->
        <beans:property name="authenticationFailureHandler"
            ref="securityLoginFailureHandler" />
        <beans:property name="authenticationSuccessHandler"
            ref="securityLoginSuccessHandler" />
        <beans:property name="PasswordParameter" value="password" /><!-- 
            change here for password field name in the form -->
        <beans:property name="UsernameParameter" value="username" /><!-- 
            change here for username field name in the form -->
    </beans:bean>

    <beans:bean id="securityLoginSuccessHandler"
        class="com.tong.beau.service.security.SecurityLoginSuccessHandler">
        <beans:property name="defaultTargetUrl" value="/" />
        <beans:property name="targetUrlParameter" value="return-url"/>
    </beans:bean>

    <beans:bean id="securityLoginFailureHandler"
        class="com.tong.beau.service.security.SecurityLoginFailureHandler">
        <beans:property name="defaultFailureUrl" value="/login/failure" />
    </beans:bean>

    <beans:bean id="securityLogoutSuccessHandler"
        class="com.tong.beau.service.security.SecurityLogoutSuccessHandler">
        </beans:bean>

    <beans:bean id="encoder"
        class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="userDetailsService">
            <password-encoder ref="encoder" />
        </authentication-provider>
    </authentication-manager>
</beans:beans>

自从我实施了 CustomAuthenticationEntryPoint 后,我​​是否需要在入口点处理记住我的服务?

看了Spring Security 4.0.3的源码,发现默认参数其实是这样定义的:

public static final String DEFAULT_PARAMETER = "remember-me";

所以我所做的就是编辑前端以发送名称为 "remember-me" 的数据。

在 Spring Security 4.0.3 之前,默认参数是 _spring_security_remember_me

值得一提。配置也有一些问题

我的工作配置如下。

<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"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

    <http pattern="/resources/**" security="none" />
    <http auto-config="false" use-expressions="true" entry-point-ref="customAuthenticationEntryPoint">

        <intercept-url pattern="/**" access="permitAll" />

        <access-denied-handler error-page="/denied" />

        <logout invalidate-session="true" delete-cookies="JSESSIONID"
            success-handler-ref="securityLogoutSuccessHandler" logout-url="/logout" />

        <custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER" />
        <custom-filter ref="rememberMeFilter" after="FORM_LOGIN_FILTER" />
        <csrf />
        <remember-me key = "remember-me" services-ref="rememberMeServices"/>
    </http>

    <beans:bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
          <beans:constructor-arg ref="authenticationManager"/>
          <beans:constructor-arg ref="rememberMeServices"/>
    </beans:bean>

    <beans:bean id="rememberMeServices"
                class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
          <beans:constructor-arg value="remember-me"/>
          <beans:constructor-arg ref="userDetailsService"/>
          <beans:constructor-arg ref="jdbcTokenRepository"/>
    </beans:bean>

    <beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <beans:constructor-arg value="remember-me"/>
    </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>

    <beans:bean id="customAuthenticationEntryPoint"
        class="com.tong.beau.service.security.CustomAuthenticationEntryPoint">
        <beans:property name="loginPageUrl" value="/login" />
        <beans:property name="returnParameterEnabled" value="true" />
        <beans:property name="returnParameterName" value="r" />
    </beans:bean>

    <beans:bean id="authenticationFilter"
        class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">

        <beans:property name="authenticationManager" ref="authenticationManager" />
        <beans:property name="rememberMeServices" ref="rememberMeServices" />
        <beans:property name="filterProcessesUrl" value="/security_check" />

        <!-- change here if customize form action -->
        <!-- handler are for login with ajax POST -->

        <beans:property name="authenticationFailureHandler"
            ref="securityLoginFailureHandler" />
        <beans:property name="authenticationSuccessHandler"
            ref="securityLoginSuccessHandler" />
        <beans:property name="PasswordParameter" value="password" />
        <!-- change here for password field name in the form -->
        <beans:property name="UsernameParameter" value="username" />
        <!-- change here for username field name in the form -->
    </beans:bean>

    <beans:bean id="securityLoginSuccessHandler"
        class="com.tong.beau.service.security.SecurityLoginSuccessHandler">
        <beans:property name="defaultTargetUrl" value="/" />
        <beans:property name="targetUrlParameter" value="return-url"/>
    </beans:bean>

    <beans:bean id="securityLoginFailureHandler"
        class="com.tong.beau.service.security.SecurityLoginFailureHandler">
        <beans:property name="defaultFailureUrl" value="/login/failure" />
    </beans:bean>

    <beans:bean id="securityLogoutSuccessHandler"
        class="com.tong.beau.service.security.SecurityLogoutSuccessHandler">
        </beans:bean>

    <beans:bean id="encoder"
        class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="rememberMeAuthenticationProvider"> 
        </authentication-provider>

        <authentication-provider user-service-ref="userDetailsService">
            <password-encoder ref="encoder" />
        </authentication-provider>
    </authentication-manager>
</beans:beans>