Spring security Remember me is not working in spring MVC application.

耗尽温柔 提交于 2019-12-23 19:25:42

问题


Authentication and Authorization is working properly. But remember me is not working properly in the application.

I have used both database authentication and ldap authentication using spring security (only one at a time) with lot of spring security customization.

Below is my spring security context file.

    <?xml version="1.0" encoding="UTF-8"?>

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

    <context:property-placeholder location="classpath:/application.properties"/>                                                        

    <http use-expressions="true">
        <intercept-url pattern="/resources/**" filters="none" />
        <intercept-url pattern="/login" access="permitAll"/>
        <intercept-url pattern="/**" access="isAuthenticated()" />
        <form-login login-page="/login"/>
        <logout invalidate-session="true"
                logout-success-url="/"
                logout-url="/logout"/>
        <remember-me key="myApp2" />
        <custom-filter before="FORM_LOGIN_FILTER" ref="applicationAuthenticationFilter"/>
    </http>

    <beans:bean id="applicationAuthenticationFilter" class="com.myApp.security.DmxAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
        <beans:property name="authenticationMethod" value="${authenticationMethod}"/>
    </beans:bean>

    <beans:bean id="successHandler"
      class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
        <beans:property name="defaultTargetUrl" value="/home"/>
        <beans:property name="alwaysUseDefaultTargetUrl" value="true"/>
    </beans:bean>

    <beans:bean id="failureHandler"
      class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <beans:property name="defaultFailureUrl" value="/login?login_error=1"/>
    </beans:bean>

    <beans:bean id="accessControlService" class="com.myApp.services.AccessControlService"/>
    <beans:bean id="userService" class="com.myApp.services.UserService"/>
    <beans:bean id="roleService" class="com.myApp.services.RoleService"/>
    <beans:bean id="lookupService" class="com.myApp.services.LookupService"/>

    <beans:bean id= "userDetailsService" class="com.myApp.security.DmxUsersDetailsServiceImpl">
        <beans:property name="accessControlService" ref="accessControlService"/> 
    </beans:bean>   

    <beans:bean id="databaseAuthenticationProvider" class="com.myApp.security.DmxAuthenticationProvider">
        <beans:property name="userDetailsService" ref="userDetailsService"/>
       <!-- <beans:property name="hideUserNotFoundExceptions" value="false"/> -->
    </beans:bean>

    <!-- ================ LDAP configuration STARTS here ================ -->

    <beans:bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">  
        <beans:constructor-arg value="${ldap.url}"/>  
        <beans:property name="userDn" value="${ldap.userDn}"/>  
        <beans:property name="password" value="${ldap.password}"/>
        <!--
        <beans:property name="baseEnvironmentProperties">
            <beans:map>
                <beans:entry key="java.naming.referral" value="follow" />
            </beans:map>
        </beans:property>
        -->
    </beans:bean>  

    <beans:bean id="ldapSearchBean" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">  
        <beans:constructor-arg value="${ldap.userSearchBase}"/>  
        <beans:constructor-arg value="${ldap.userSearchFilter}"/>  
        <beans:constructor-arg ref="ldapServer"/>  
    </beans:bean>  

    <beans:bean id="ldapAuthenticationProvider" class="com.myApp.security.DmxLdapAuthenticationProvider">  
        <beans:constructor-arg ref="ldapBindAuthenticator"/>  
        <beans:constructor-arg ref="ldapAuthoritiesPopulator"/>  
        <beans:property name="userDetailsContextMapper" ref="ldapUserDetailsContextMapper"/>  
    </beans:bean> 

    <beans:bean id="ldapBindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator">  
        <beans:constructor-arg ref="ldapServer"/>  
        <beans:property name="userSearch" ref="ldapSearchBean"/>  
    </beans:bean>  

    <beans:bean id="ldapAuthoritiesPopulator" class="com.myApp.security.DmxLdapAuthoritiesPopulator">
        <beans:constructor-arg ref="ldapServer" />
        <beans:constructor-arg value="" />
        <beans:property name="groupSearchFilter" value="${ldap.groupSearchFilter}"/>
        <beans:property name="groupRoleAttribute" value="${ldap.groupRoleAttribute}" />
        <beans:property name="rolePrefix" value=""/>
        <beans:property name="searchSubtree" value="true"/>
        <beans:property name="convertToUpperCase" value="false"/>
        <beans:property name="ldapTemplate" ref="ldapTemplate"/> 
    </beans:bean>

    <beans:bean id= "dmxUsersMapper" class="com.myApp.security.DmxUsersMapper">
        <beans:property name="accessControlService" ref="accessControlService"/>
        <beans:property name="userService" ref="userService"/>
        <beans:property name="roleService" ref="roleService"/>
        <beans:property name="lookupService" ref="lookupService"/>
        <beans:property name="organizationUname" value="${organizationUname}"/>
        <beans:property name="companyUname" value="${companyUname}"/>
        <beans:property name="ldapUsername" value="${ldap.db.userName}"/>
        <beans:property name="password" value="${ldap.db.password}"/>
    </beans:bean>    

    <beans:bean class="com.myApp.security.DmxLdapUserDetailsMapper" id="ldapUserDetailsContextMapper">
        <beans:property name="dmxUsersMapper" ref="dmxUsersMapper"/> 
    </beans:bean>

    <beans:bean id="ldapTemplate" class="org.springframework.security.ldap.SpringSecurityLdapTemplate">
        <beans:constructor-arg ref="ldapServer" />
        <beans:property name="ignorePartialResultException" value="true"/>
    </beans:bean>

    <!-- ================ LDAP configuration ENDS here ================ -->

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

    <beans:bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <beans:property name="basenames">
            <beans:list>
                <beans:value>com/myApp/resourceBundles/SecurityMessages</beans:value>
            </beans:list>
        </beans:property>            
    </beans:bean>

</beans:beans>

Below is my login page.

    <form action="j_dmx_security_filter" method="post">
    <table border="0" class="section_tbl2">
        <tr>
            <td><label for="j_organization">Organization</label> </td>
            <td> : </td>
            <td><input id="j_organization" name="j_organization" size="20" maxlength="50"
                       type="text" class="txtinput"/></td>
        </tr>

        <tr>
            <td> <label for="j_company">Company</label></td>
            <td> : </td>
            <td> <input id="j_company" name="j_company" size="20" maxlength="50"
                        type="text" class="txtinput"/></td>
        </tr>
        <tr>
            <td><label for="j_username">Username</label>  </td>
            <td> : </td>
            <td><input id="j_username" name="j_username" size="20" maxlength="50"
                       type="text" class="txtinput"/></td>
        </tr>
        <tr>
            <td><label for="j_password">Password</label>  </td>
            <td> : </td>
            <td><input id="j_password" name="j_password" size="20" maxlength="50"
                       type="password" class="txtinput"/></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td> <input type="submit" value="Login"/></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td> <input id="_spring_security_remember_me" name="_spring_security_
                        remember_me" type="checkbox" value="true"/>
                <label for="_spring_security_remember_me">Remember Me?</label></td>
        </tr>
    </table>
</form>

The remember me token itself is not getting created.

Please help.


回答1:


in order to help, where are your relevant beans definitions of the RememberMe? such as

<bean id="rememberMeServices" class=
        "org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <property name="userDetailsService" ref="jpaUserDetailsService"/>
    <property name="key" value="89dqj219dn910lsAc12"/>
</bean>

<bean id="rememberMeAuthenticationProvider" class=
        "org.springframework.security.authentication.RememberMeAuthenticationProvider">
    <property name="key" value="89dqj219dn910lsAc12"/>
</bean>

(this is too long to be written as a comment, so I wrote it as an "answer"... sorry)




回答2:


In the Spring security they provide 2 ways to use the rememberMe service.

  1. In the rememberMeService Definition, set a property alwaysRememberMe is true. In this case whenever first time user try to access the secure URL it will take to login page. once user logged in with correct user name and password, after onwards it wil not ask you for login until you logout.

  2. In the login page add a remember me checkbox with name "_spring_security_remember_me" and value="true". In this case when user select the remember me check box then only it will able to access to secure URL without login page until u logout.

Its working for me..




回答3:


This is how I did and it worked....complete sample of working code is available HERE

<security:http use-expressions='true'>
    <security:intercept-url pattern="/protected" access="isAuthenticated()"/>
    <security:intercept-url pattern="/**" access="permitAll"/>
    <security:form-login login-page="/login" authentication-failure-url="/login?login_error=1" />
    <security:logout logout-url="/j_spring_security_logout" />
    <security:remember-me services-ref="rememberMeServices" key="testKeyForBlog" />
</security:http>

<bean id="rememberMeServices"
      class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
    <property name="tokenRepository" ref="customTokenRepository" />
    <property name="userDetailsService" ref="userDetailsService" />
    <property name="key" value="testKeyForBlog" />
</bean>



回答4:


You have to use rememberMeService and pass it to your applicationAuthenticationFilter

rememberMeSevice will be like

<beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <beans:property name="userDetailsService" ref="userDetailsService" />
    <beans:property name="key" value="myApp2" />
</beans:bean>

Your Authentication will be

<beans:bean id="applicationAuthenticationFilter" class="com.myApp.security.DmxAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="rememberMeServices" ref="rememberMeServices" />
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
        <beans:property name="authenticationMethod" value="${authenticationMethod}"/>
    </beans:bean>

This should work



来源:https://stackoverflow.com/questions/8226097/spring-security-remember-me-is-not-working-in-spring-mvc-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!