JSF 2.1 und Spring 3 Security Login mit RememberMe

Kian

Aktives Mitglied
Hallo,

ich versuche nun schon seit einigen Tagen einen rememberMe-Login mit JSF 2.1 (MyFaces) und Spring 3 Security hinzubekommen und komme einfach nicht weiter.

Ich habe eine Spring-Bean(Component), die die Login-Daten aufnimmt und die Methode "login()" um den login durchzuführen (in der selben Bean).

Der Login funktioniert an sich auch, nur wird bei einer manuellen Eingabe der URL im Browser zum einen die aktuelle Session nicht erkannt (es wird zur Login Seite weitergeleitet) und zum anderen wird das RememberMe komplett ignoriert, d.h. neustarten des Browsers und erneuter Aufruf der Seite funktioniert ebenfalls nicht (man wird zur Login-Seite weitergeleitet).

Die Bean:
Die return Werte sind die Outcomes der Navigation-Rules (login() wird über CommandButton action aufgerufen).

Java:
public String login() {
		
		try {
			Authentication result = null;
			if (this.rememberMe) {
				UserDetails userDetails = userDetailsService.loadUserByUsername(this.name);
				RememberMeAuthenticationToken rememberMeAuthenticationToken = new RememberMeAuthenticationToken(
						"jsfspring-sec", userDetails,
						userDetails.getAuthorities());
				HttpServletRequest httpServletRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
				HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
				rememberMeServices.loginSuccess(httpServletRequest, httpServletResponse, rememberMeAuthenticationToken);
				result = rememberMeAuthenticationToken;
			} else {
				Authentication request = new UsernamePasswordAuthenticationToken(
						this.name, this.password);
				result = this.autManager.authenticate(request);
			}
			SecurityContextHolder.getContext().setAuthentication(result);
		} catch (AuthenticationException e) {
			e.printStackTrace();
			return "failed";
		}
		
		return "login";
	}

Meine "spring-security.xml" Spring Security Config:
[XML]
<http auto-config="true">

<intercept-url pattern="/welcome/*" access="ROLE_USER" />
<intercept-url pattern="/login.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY" />

<form-login login-page="/login.xhtml"/>

<logout invalidate-session="true" delete-cookies="true" logout-success-url="/"/>
</http>

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

<user-service id="userDetailsService">
<user name="user" password="user" authorities="ROLE_USER" />
</user-service>

</authentication-provider>
</authentication-manager>
[/XML]

Meine "applicationContext.xml" Spring Security Config:
[XML]
<import resource="spring-security.xml"/>

<context:component-scan base-package="com.test.component" />
<context:annotation-config />

<bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="key" value="jsfspring-sec" />
<property name="userDetailsService" ref="userDetailsService" />
<property name="alwaysRemember" value="true" />
<property name="tokenValiditySeconds" value="300" />
</bean>

<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="jsfspring-sec"/>
</bean>

<bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
[/XML]

Meine "web.xml" Spring Security Config:
[XML]
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[/XML]

Weiß irgendjemand wo der Fehler liegt?
 
Hab' die Lösung gefunden:

In der "security-context.xml" zwischen die html-tags noch folgendes hinzufügen:

[XML]
<remember-me key="jsfspring-sec" services-ref="rememberMeServices"/>
[/XML]

Dadurch funktioniert das einfache Remember-Me (hätte das Tutorial gründlicher durchlesen sollen statt es zu überfliegen).

In der selben Datei kann man nun auch den authenticationProvider (mit der ref zum "rememberMeAuthenticationProvider") für das Remember-Me entfernen.
Ist im Tutorial zwar drin, macht meiner Meinung nach keinen Sinn und es funktioniert alles auch ohne.

Was die verlorenen Sessions angeht scheint dies wohl ein Logikfehler von mir gewesen zu sein.
Das Navigieren der Seiten scheint so zu funktionieren (soweit ich es verstanden habe; ohne RememberMe und ohne redirect):

Man versucht eine gesicherte Seite aufzurufen und landet beim Login (login.xhtml).
Man führt den login durch und landet auf der Seite(welcome.xhtml) nach dem Login.
Man kann die welcome.xhtml nicht per URL erneut aufrufen.
Erst nachdem man sich von der Seite per Link auf eine weitere Seite wechselt(welcome2.xhtml), ist die Seite(welcome.xhtml) per URL aufrufbar.

Dies lässt darauf schließen, dass momentane Seiten (welche per jsf-forward aufgerufen wurden) nicht in der Session "gespeichert" werden (dies gilt natürlich auch für Seiten die man noch nicht besucht hat).
Die Seiten, die man jedoch besucht UND verlassen hat (per Link/Button) sind jedoch in der Session "abgelegt".
Es exisitiert für diese Seiten also eine Art ViewState.

Falls ich das falsch erklärt habe, dann sagt bescheid.
 

Zurück
Oben