Pas de redirection sur "remember me"
Bonjour,
en migrant un projet J2EE utilisant l'authentification de Spring Security, je me retrouve confronté avec un problème à propos de celle-ci:
la fonction "remember me" ne fonctionne pas => aucune redirection n'est effectuée. Plus précisément, le cookie "SPRING_SECURITY_REMEMBER_ME_COOKIE" est bien présent mais je reste sur ma page de login malgré tout.
A ce sujet, j'ai essayé plusieurs choses... sans succès.
Pour préciser, la personne qui avait mis en place l'authentification avait fait le choix d'un cookie (et non d'un stockage en table); ce choix là ne sera pas remis en cause. Je dois donc faire marcher ce qui existe.
Voici ma conf :
appContext-security.xml
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<!-- B2B http section -->
<http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint">
<intercept-url pattern="/app/login/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<quelques-autres-filtres="..."/>
<port-mappings>
<port-mapping http="80" https="443"/>
</port-mappings>
<anonymous/>
<remember-me/>
<logout logout-success-url="/app/public/presentation/presentation.jsf"
invalidate-session="true"
/>
</http>
<beans:bean id="myCustomUserService"
class="com.foo.monapp.app.technique.security.spring.service.MyCustomUserDetailsService">
<beans:property name="userDao" ref="userDao" />
<beans:property name="userGroupDao" ref="userGroupDao" />
<beans:property name="targetWebapp" value="app"></beans:property>
</beans:bean>
<authentication-provider user-service-ref="myCustomUserService">
<password-encoder hash="sha-256" />
</authentication-provider>
<authentication-manager alias="authenticationManagerAlias" />
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="com.foo.monapp.view.security.spring.AjaxAuthenticationProcessingFilterEntryPoint">
<beans:property name="loginFormUrl" value="/app/public/presentation/presentation.jsf" />
<beans:property name="serverSideRedirect" value="true" />
</beans:bean>
<beans:bean id="customAuthenticationProcessingFilter" class="com.foo.monapp.view.security.spring.AjaxAuthenticationProcessingFilter">
<beans:property name="defaultTargetUrl" value="/app/home/home.jsf" />
<beans:property name="alwaysUseDefaultTargetUrl" value="true" />
<beans:property name="authenticationFailureUrl" value="/app/public/presentation/presentation.jsf" />
<beans:property name="authenticationManager" ref="authenticationManagerAlias" />
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</beans:bean>
<beans:bean id="customAuthenticationProvider" class="com.foo.monapp.view.security.spring.CustomAuthenticationProvider">
<custom-authentication-provider />
<beans:property name="userDetailsService" ref="myCustomUserService" />
</beans:bean>
<beans:bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener" />
</beans:beans> |
le web.xml (la partie qui nous intéresse)
Code:
1 2 3 4 5 6 7 8 9 10
| <filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping> |
l'authentification:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class AjaxAuthenticationProcessingFilter extends AuthenticationProcessingFilter {
protected String determineTargetUrl(final HttpServletRequest request) {
SavedRequest savedRequest = getSavedRequest(request);
if (savedRequest != null && isAjaxRequest(savedRequest)) {
return getDefaultTargetUrl();
} else {
return super.determineTargetUrl(request);
}
}
public static SavedRequest getSavedRequest(final HttpServletRequest request) {
return (SavedRequest) request.getSession().getAttribute(AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY);
}
private boolean isAjaxRequest(final SavedRequest request) {
return null != request.getParameterMap().get(AjaxContainerRenderer.AJAX_PARAMETER_NAME);
}
} |
J'avais également essayé d'ajouter un filtre personnalisé sur le remember me... mais j'avais un conflit d'"ordre" (il était apparemment en conflit avec celui par défaut, alors que je pensais qu'il le remplaçait). J'ai donc rajouté le listener "avant"... mais je ne rentre dedans (via la méthode doFilterHttp) que lors d'une authentification classique, et non lors d'une situation de "remember me".
Code:
1 2 3 4 5 6 7
| <beans:bean id="customRememberMeProcessingFilter" class="com.foo.monapp.view.security.spring.CustomRememberMeProcessingFilter">
<beans:property name="defaultTargetUrl" value="/app/home/home.jsf" />
<beans:property name="rememberMeServices" ref="_rememberMeServices" />
<beans:property name="authenticationManager" ref="authenticationManagerAlias" />
<custom-filter before="REMEMBER_ME_FILTER"/>
</beans:bean> |
Voilà... si quelqu'un voit ce que je dais de mal... ou que je ne fais pas ici!
Juste pour info, le formulaire de login est écrit en JSF et -me semble t'il - très classique :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <h:inputText
type="text"
id="j_username"
name="j_username"
value="#{user.login}"/>
<h:inputSecret
id="j_password"
name="j_password"
value="#{user.password}"/>
<h:selectBooleanCheckbox
id="_spring_security_remember_me"
name="_spring_security_remember_me"
value="#{user.rememberme}" />
<h:commandLink action="#{user.doLogin}" id="submitlink">
<span>login</span>
</h:commandLink> |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| /**
* Action login.
*
* @return an outcome
* @throws IOException an i/o exception
* @throws ServletException a servlet related exception
*/
public final String doLogin() throws IOException, ServletException {
final ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
final HttpServletRequest request = ((HttpServletRequest) context.getRequest());
final RequestDispatcher dispatcher = request.getRequestDispatcher("/j_spring_security_check");
dispatcher.forward(request, (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
return null;
} |