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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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;
 
    }