Spring security Remember-me doesn't work -
i'm trying apply spring security custom user detail service , custom authentication provider. also, i'm trying apply remember-me functionality.
however, somehow, after configured custom user detail service , custom authentication provider, remember me stop working.
when check cookies client browser, has remember-me cookie. but, if redeploy (restart) server or restart client browser, redirects login page.
here i'm attaching configuration , custom files.
<?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:security="http://www.springframework.org/schema/context" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- enable use-expressions --> <security:annotation-config/> <http auto-config="false" use-expressions="true"> <headers> <cache-control /> </headers> <intercept-url pattern="/resources/**" access="permitall()"/> <intercept-url pattern="/signin" access="permitall()" /> <intercept-url pattern="/403" access="permitall()" /> <intercept-url pattern="/**" access="hasrole('role_user')" /> <!-- redirect 403 access denied <intercept-url pattern="/update**" access="hasrole('role_admin') , isfullyauthenticated()" /> --> <form-login login-page="/signin" default-target-url="/" authentication-failure-url="/signin?error" username-parameter="username" password-parameter="password" login-processing-url="/auth/login_check" authentication-success-handler-ref="loginsuccesshandler" /> <logout logout-url="/logout" logout-success-url="/signin?logout" delete-cookies="jsessionid" /> <!-- enable csrf protection --> <!--<csrf disabled="true"/>--> <!--<remember-me--> <!--token-validity-seconds="1209600"--> <!--remember-me-parameter="remember-me"--> <!--data-source-ref="datasource" user-service-ref="customuserdetailservice"/>--> <remember-me services-ref="remembermeservices" /> <csrf disabled="true"/> <!--<custom-filter ref="statelesscsrffilter" before="csrf_filter"/>--> </http> <!-- select users , user_roles database --> <!--<authentication-manager>--> <!--<authentication-provider>--> <!--<jdbc-user-service data-source-ref="datasource"--> <!--users-by-username-query="select username,password, enabled users username=?"--> <!--authorities-by-username-query="select username, role user_roles username =? "--> <!--group-authorities-by-username-query="select g.id, g.group_name, ga.authority groups g, group_members gm, group_authorities ga gm.username = ? , g.id = ga.group_id , g.id = gm.group_id"/>--> <!--</authentication-provider>--> <!--</authentication-manager>--> <beans:bean id="customuserdetailservice" class="com.euroscope.app.service.security.customuserservice"></beans:bean> <beans:bean id="customauthenticationprovider" class="com.euroscope.app.handler.customauthenticationprovider"></beans:bean> <beans:bean id="loginsuccesshandler" class="com.euroscope.app.handler.loginsuccesshandler"></beans:bean> <!--<beans:bean id="statelesscsrffilter" class="com.euroscope.app.filter.statelesscsrffilter" />--> <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="euroscope"/> <beans:constructor-arg ref="customuserdetailservice"/> <beans:constructor-arg ref="tokenrepository" /> <beans:property name="alwaysremember" value="true" /> </beans:bean> <beans:bean id="remembermeauthenticationprovider" class= "org.springframework.security.authentication.remembermeauthenticationprovider"> <beans:constructor-arg value="euroscope"/> </beans:bean> <beans:bean id="tokenrepository" class="org.springframework.security.web.authentication.rememberme.jdbctokenrepositoryimpl"> <beans:property name="datasource" ref="datasource"/> </beans:bean> <authentication-manager alias="authenticationmanager"> <authentication-provider ref="remembermeauthenticationprovider" /> <authentication-provider ref="customauthenticationprovider" /> <authentication-provider user-service-ref="customuserdetailservice" /> </authentication-manager> </beans:beans> login success handler
@component @slf4j public class loginsuccesshandler extends savedrequestawareauthenticationsuccesshandler { @override public void onauthenticationsuccess(httpservletrequest request, httpservletresponse response, authentication auth) throws ioexception, servletexception { httpsession session = request.getsession(); employee employee = (employee)auth.getprincipal(); log.debug("employee : "+employee); session.setattribute("employee",employee); response.sendredirect(request.getcontextpath() + "/"); } } package com.euroscope.app.handler; import com.euroscope.app.domain.security.employee; import com.euroscope.app.service.security.customuserservice; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.security.authentication.authenticationprovider; import org.springframework.security.authentication.badcredentialsexception; import org.springframework.security.authentication.usernamepasswordauthenticationtoken; import org.springframework.security.core.authentication; import org.springframework.security.core.authenticationexception; import org.springframework.security.core.grantedauthority; import org.springframework.security.core.userdetails.usernamenotfoundexception; import org.springframework.stereotype.component; import java.util.collection; /** * created ksyeng on 7/9/15. */ @component public class customauthenticationprovider implements authenticationprovider { private static final logger logger = loggerfactory.getlogger(customauthenticationprovider.class); @autowired customuserservice customuserservice; @override public authentication authenticate(authentication authentication) throws authenticationexception { string username = authentication.getname(); string password = (string) authentication.getcredentials(); employee employee; collection<? extends grantedauthority> authorities; try { logger.debug("custom authentication : "+authentication); employee = (employee)customuserservice.loaduserbyusername(username); // employee = customuserservice.loaduserbyusername(username); // string hashedpassword = passwordencoder.encodepassword(password, saltsource.getsalt(user)); // log.info("username : " + username + " / password : " + password + " / hash password : " + hashedpassword); logger.debug("username : " + employee.getusername() + " / password : " + employee.getpassword()); // if (!hashedpassword.equals(user.getpassword())) throw new badcredentialsexception("비밀번호가 일치하지 않습니다."); authorities = employee.getauthorities(); return new usernamepasswordauthenticationtoken(employee, password, authorities); } catch(usernamenotfoundexception e) { e.printstacktrace(); logger.debug(e.tostring()); throw new usernamenotfoundexception(e.getmessage()); } catch(badcredentialsexception e) { e.printstacktrace(); logger.debug(e.tostring()); throw new badcredentialsexception(e.getmessage()); } catch(exception e) { e.printstacktrace(); logger.debug(e.tostring()); throw new runtimeexception(e.getmessage()); } } @override public boolean supports(class<?> aclass) { return true; } } custom user service
package com.euroscope.app.service.security; import com.euroscope.app.domain.security.employee; import com.euroscope.app.domain.security.role; import com.euroscope.app.mapper.security.usermapper; import lombok.extern.slf4j.slf4j; import org.springframework.security.core.userdetails.userdetails; import org.springframework.security.core.userdetails.userdetailsservice; import org.springframework.security.core.userdetails.usernamenotfoundexception; import org.springframework.stereotype.service; import javax.annotation.resource; import java.util.arraylist; /** * created ksyeng on 7/9/15. */ @slf4j @service public class customuserservice implements userdetailsservice { @resource private usermapper usermapper; @override public userdetails loaduserbyusername(string username) throws usernamenotfoundexception { employee employee = usermapper.getuser(username); arraylist<role> authlist = usermapper.getroles(username); log.debug("auth roles : "+authlist.tostring()); employee.setauthorities(authlist); if(employee == null){ throw new usernamenotfoundexception("can't find matching user"); } log.debug(employee.tostring()); return employee; } }
whatever authentication filters (ie, subclasses of abstractauthenticationprocessingfilter) using need aware of remembermeservices, example:
<beans:bean .. class="x.x..yourcustomauthenticationfilter"> <beans:property name="remembermeservices" ref="remembermeservices"/> <beans:property name="authenticationmanager" ref="authenticationmanager"/> </beans:bean> and remembermeauthenticationfilter should registered after yourcustomauthenticationfilter
Comments
Post a Comment