From c0e829a41dfb06c2c969ba9c5545b19b0f715b9f Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Thu, 8 May 2008 15:59:01 +0000 Subject: [PATCH] SEC-700: Added info on new remember-me imlementation and namespace config examples --- src/docbkx/remember-me-authentication.xml | 199 ++++++++++++++-------- 1 file changed, 127 insertions(+), 72 deletions(-) diff --git a/src/docbkx/remember-me-authentication.xml b/src/docbkx/remember-me-authentication.xml index 5aa21a7443..a68ca8b1f0 100644 --- a/src/docbkx/remember-me-authentication.xml +++ b/src/docbkx/remember-me-authentication.xml @@ -1,22 +1,88 @@ -Remember-Me Authentication + + Remember-Me Authentication
Overview - - - Remember-me authentication refers to web sites being able to + + Remember-me or persistent-login authentication refers to web sites being able to remember the identity of a principal between sessions. This is typically accomplished by sending a cookie to the browser, with the cookie being detected during future sessions and causing automated - login to take place. Spring Security provides the necessary hooks so - that such operations can take place, along with providing a concrete - implementation that uses hashing to preserve the security of - cookie-based tokens. + login to take place. Spring Security provides the necessary hooks for + these operations to take place, and has two concrete + remember-me implementations. One uses hashing to preserve the security of + cookie-based tokens and the other uses a database or other persistent storage + mechanism to store the generated tokens.
- -
Configuration +
+ Simple Hash-Based Token Approach + This approach uses hashing to achieve a useful remember-me strategy. + In essence a cookie is sent to the browser upon successful interactive authentication, with the + cookie being composed as follows: + + base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key)) + + username: As identifiable to the UserDetailsService + password: That matches the one in the retrieved UserDetails + expirationTime: The date and time when the remember-me token expires, expressed in milliseconds + key: A private key to prevent modification of the remember-me token + + + As such the remember-me token is valid only for the period + specified, and provided that the username, password and key does not + change. Notably, this has a potential security issue in that a + captured remember-me token will be usable from any user agent until + such time as the token expires. This is the same issue as with digest + authentication. If a principal is aware a token has been captured, + they can easily change their password and immediately invalidate all + remember-me tokens on issue. If more significant security is + needed you should use the approach described in the next section. Alternatively + remember-me services should simply not be used at all. + + If you are familiar with the topics discussed in the chapter on namespace configuration, + you can enable remember-me authentication just by adding the <remember-me> element: + + ... + + + ]]> + + It is automatically enabled for you if you are using the auto-config setting. + Note that remember-me requires a UserDetailsService. If you are using an authentication + provider which doesn't use a UserDetailsService (for example, the LDAP provider) then it won't work + unless you also have a UserDetailsService bean in your application context. If you have more than one, + you need to specify which one should be used with the user-service-ref attribute. + +
+ +
+ Persistent Token Approach + This approach is based on the article + http://jaspan.com/improved_persistent_login_cookie_best_practice + with some minor modifications Essentially, the username is not included in the cookie, to prevent exposing a valid login + name unecessarily. There is a discussion on this in the comments section of this article.. + To use the this approach with namespace configuration, you would supply a datasource reference: + + ... + + + ]]> + + The database should contain a persistent_logins table, created using the following SQL (or equivalent): + + create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null) + + + +
+ +
+ Remember-Me Interfaces and Implementations Remember-me authentication is not used with basic authentication, given it is often not used with @@ -31,67 +97,42 @@ void loginFail(HttpServletRequest request, HttpServletResponse response); void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication); - Please refer to JavaDocs for a fuller discussion on what the - methods do, although note at this stage + Please refer to the JavaDocs for a fuller discussion on what the + methods do, although note at this stage that AbstractProcessingFilter only calls the loginFail() and loginSuccess() methods. The autoLogin() method is called by RememberMeProcessingFilter whenever the SecurityContextHolder does not contain an Authentication. This interface therefore provides - the underlaying remember-me implementation with sufficient + the underlying remember-me implementation with sufficient notification of authentication-related events, and delegates to the implementation whenever a candidate web request might contain a cookie - and wish to be remembered. - - This design allows any number of remember-me implementation - strategies. In the interests of simplicity and avoiding the need for - DAO implementations that specify write and create methods, Acegi - Security's only concrete implementation, - TokenBasedRememberMeServices, uses hashing to - achieve a useful remember-me strategy. In essence a cookie is sent to - the browser upon successful interactive authentication, with that - cookie being composed as follows: - - -base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key)) + and wish to be remembered. This design allows any number of remember-me implementation + strategies. We've seen above that Spring Security provides + two implementations. We'll look at thes in turn. -username: As identifiable to TokenBasedRememberMeServices.getUserDetailsService() -password: That matches the relevant UserDetails retrieved from TokenBasedRememberMeServices.getUserDetailsService() -expirationTime: The date and time when the remember-me token expires, expressed in milliseconds -key: A private key to prevent modification of the remember-me token - - - As such the remember-me token is valid only for the period - specified, and provided that the username, password and key does not - change. Notably, this has a potential security issue in that a - captured remember-me token will be usable from any user agent until - such time as the token expires. This is the same issue as with digest - authentication. If a principal is aware a token has been captured, - they can easily change their password and immediately invalidate all - remember-me tokens on issue. However, if more significant security is - needed a rolling token approach should be used (this would require a - database) or remember-me services should simply not be used. - - TokenBasedRememberMeServices generates a - RememberMeAuthenticationToken, which is processed - by RememberMeAuthenticationProvider. A - key is shared between this authentication provider - and the TokenBasedRememberMeServices. In addition, - TokenBasedRememberMeServices requires A - UserDetailsService from which it can retrieve the username and - password for signature comparison purposes, and generate the - RememberMeAuthenticationToken to contain the - correct GrantedAuthority[]s. Some sort of logout - command should be provided by the application (typically via a JSP) - that invalidates the cookie upon user request. See the Contacts Sample - application's logout.jsp for an example. - - The beans required in an application context to enable - remember-me services are as follows: - - - + TokenBasedRememberMeServices + + This implementation supports the simpler approach described in . + TokenBasedRememberMeServices generates a + RememberMeAuthenticationToken, which is processed + by RememberMeAuthenticationProvider. A + key is shared between this authentication provider + and the TokenBasedRememberMeServices. In addition, + TokenBasedRememberMeServices requires A + UserDetailsService from which it can retrieve the username and + password for signature comparison purposes, and generate the + RememberMeAuthenticationToken to contain the + correct GrantedAuthority[]s. Some sort of logout + command should be provided by the application that invalidates the cookie if + the user requests this. TokenBasedRememberMeServices also implements Spring Security's + LogoutHandler interface so can be used with LogoutFilter + to have the cookie cleared automatically. + + The beans required in an application context to enable remember-me services are as follows: + @@ -107,14 +148,28 @@ key: A private key to prevent modification of the remember-me token ]]> - Don't forget to add your - RememberMeServices implementation to your - AuthenticationProcessingFilter.setRememberMeServices() - property, include the - RememberMeAuthenticationProvider in your - AuthenticationManager.setProviders() list, and add - a call to RememberMeProcessingFilter into your - FilterChainProxy (typically immediately after your - AuthenticationProcessingFilter) -
+ Don't forget to add your + RememberMeServices implementation to your + AuthenticationProcessingFilter.setRememberMeServices() + property, include the + RememberMeAuthenticationProvider in your + AuthenticationManager.setProviders() list, and add + RememberMeProcessingFilter into your + FilterChainProxy (typically immediately after your + AuthenticationProcessingFilter) +
+
+ PersistentTokenBasedRememberMeServices + + This class can be used in the same way as TokenBasedRememberMeServices, but it additionally + needs to be configured with a PersistentTokenRepository to store the tokens. + There are two standard implementations. + + InMemoryTokenRepositoryImpl which is intended for testing only. + JdbcTokenRepositoryImpl which stores the tokens in a database. + + The database schema is described above in . + +
+
\ No newline at end of file