views:

1686

answers:

3

I've been trying to track down why Spring Security isn't creating the Spring Security remember me cookie (SPRING_SECURITY_REMEMBER_ME_COOKIE). However, based on what I see via the HTTP headers the cookie is being set it's just that there is an additional GET request for /j_spring_security_check that is causing the exception below. This also results in the cookie being removed.

FINE: Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Authentication method not supported: GET

I'm using Spring 3.0.1, Spring Security 3.0.3 Snapshot, and Google App Engine 1.3.1. Any ideas as to what is going on?

Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter doFilter
FINE: Request is to process authentication
Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter unsuccessfulAuthentication
FINE: Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Authentication method not supported: GET
Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter unsuccessfulAuthentication
FINE: Updated SecurityContextHolder to contain null Authentication
Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter unsuccessfulAuthentication
FINE: Delegating to authentication failure handlerorg.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@4196c169
Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices loginFail
FINE: Interactive login attempt was unsuccessful.
Mar 17, 2010 10:38:35 AM org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices cancelCookie
FINE: Cancelling cookie

Below is the relevant portion of the applicationContext-security.xml.

<http auto-config="false">
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/img/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/app/admin/**" filters="none" />
    <intercept-url pattern="/app/login/**" filters="none" />
    <intercept-url pattern="/app/register/**" filters="none" />
    <intercept-url pattern="/app/error/**" filters="none" />
    <intercept-url pattern="/" filters="none" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <logout logout-success-url="/" />
    <form-login login-page="/app/login" default-target-url="/" authentication-failure-url="/app/login?login_error=1" />
    <session-management invalid-session-url="/app/login" />
    <remember-me services-ref="rememberMeServices" key="myKey" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha-256" base64="true">
            <salt-source user-property="username" />
        </password-encoder>
    </authentication-provider>
</authentication-manager>

<beans:bean id="userDetailsService" class="com.my.service.auth.UserDetailsServiceImpl" />

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

<beans:bean id="persistentTokenRepository" class="com.my.service.auth.PersistentTokenRepositoryImpl" />

Below are the http headers for the scenario I'm having issues with:

http://localhost:8080/j_spring_security_check

POST /j_spring_security_check HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://localhost:8080/app/login
Cookie: JSESSIONID=15t2gq1vo5noj
Content-Type: application/x-www-form-urlencoded
Content-Length: 88
j_username=test%40test.com&j_password=test&_spring _security_remember_me=on&submit=Submit
HTTP/1.1 302 Found
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: JSESSIONID=1dymxpkh13z32;Path=/
Set-Cookie: SPRING_SECURITY_REMEMBER_ME_COOKIE=U05kS2NTakNIZTN Dd0hFcWxqZXRUQT09Oi90M3Q0NTA1czhxSjRadTQ5NW5FQVE9P Q;Path=/;Expires=Wed, 31-Mar-10 10:52:07 GMT
Location: http://localhost:8080/app/helloWorld
Content-Length: 0
Server: Jetty(6.1.x)
----------------------------------------------------------
http://localhost:8080/app/helloWorld

GET /app/helloWorld HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://localhost:8080/app/login
Cookie: JSESSIONID=1dymxpkh13z32; SPRING_SECURITY_REMEMBER_ME_COOKIE=U05kS2NTakNIZTN Dd0hFcWxqZXRUQT09Oi90M3Q0NTA1czhxSjRadTQ5NW5FQVE9P Q

HTTP/1.1 200 OK
Content-Language: en-US
Content-Type: text/html
Content-Length: 526
Server: Jetty(6.1.x)
----------------------------------------------------------
http://localhost:8080/j_spring_security_check

GET /j_spring_security_check HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: JSESSIONID=1dymxpkh13z32; SPRING_SECURITY_REMEMBER_ME_COOKIE=U05kS2NTakNIZTN Dd0hFcWxqZXRUQT09Oi90M3Q0NTA1czhxSjRadTQ5NW5FQVE9P Q

HTTP/1.1 302 Found
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: SPRING_SECURITY_REMEMBER_ME_COOKIE=;Path=/;Expires=Thu, 01 Jan 1970 00:00:00 GMT
Location: http://localhost:8080/app/login?login_error=1
Content-Length: 0
Server: Jetty(6.1.x)
----------------------------------------------------------
http://localhost:8080/app/login?login_error=1

GET /app/login?login_error=1 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: JSESSIONID=1dymxpkh13z32

HTTP/1.1 200 OK
Content-Language: en-US
Content-Type: text/html
Content-Length: 928
Server: Jetty(6.1.x)
A: 

Have you tried using the simplest version of remember-me ?

<remember-me key="myAppKey"/>

Could be that your custom implementation of the token repository is at fault. What does your PersistentTokenRepositoryImpl actually do?

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html

matt b
I have to implement my own PersistentTokenRepository because I have to interact with the App Engine Datastore. I've confirmed that the persistentTokenRepository.createNewToken() call persists to the datastore successfully.
Taylor Leese
I've even been able to track it down to UsernamePasswordAuthenticationFilter.successfulAuthentication(...)
Taylor Leese
I updated the question with more information in case you have any ideas.
Taylor Leese
If I understand the http headers correctly, looks like you POST to j_spring_security_check, it redirects you to /app/helloWorld (which I assume means authentication worked ok), you browser GETs the helloWorld page ... but after that there is a GET request to j_spring_security_check. What is generating this GET request in your client/webpage?
matt b
That is the real question. I don't know what is causing it. I assume it's either something wrong in my configuration or a Spring Security bug.
Taylor Leese
I don't see how it's possible that anything in Spring Security could be generating a HTTP GET request from your browser. Are you sure you don't have any errant links or javascript or anything else in your HTML layer?
matt b
It turns out that Firebug was generating the additional GET request.
Taylor Leese
A: 

Remember Me was broken in Spring Security 3.0.1: SEC-1356. Use 3.0.2.

axtavt
The status of that bug is "won't fix" so how would 3.0.2 help? It looks like there was no change made.
Taylor Leese
Perhaps if I use Spring Security 3.0.0 that would work? I can't use Spring Security 3.0.2 because of this issue: http://jira.springframework.org/browse/SEC-1434.
Taylor Leese
@Taylor: Yes, in 3.0.0 it should work. It's marked "won't fix", because the original issue was incorrectly resolved (breaking everything) in 3.0.1 and reverted in 3.0.2.
axtavt
I see. I will give 3.0.0 a try. Thanks.
Taylor Leese
I tried both Spring Security 3.0.0 and the 3.0.3 snapshot and I'm still seeing the same issue. Any other ideas?
Taylor Leese
I updated the question with more information in case you have any ideas.
Taylor Leese
+1  A: 

Turns out that Firebug was generating the additional GET request.

Taylor Leese