diff --git a/docs/manual/src/docbook/core-services.xml b/docs/manual/src/docbook/core-services.xml index 748c4b0df9..74097c4b92 100644 --- a/docs/manual/src/docbook/core-services.xml +++ b/docs/manual/src/docbook/core-services.xml @@ -73,24 +73,23 @@ authenticate is made.
Erasing Credentials on Successful Authentication - - By default (from Spring Security 3.1 onwards) the ProviderManager - will attempt to clear any sensitive credentials information from the - Authentication object which is returned by a successful - authentication request. This prevents information like passwords being retained longer - than necessary. - - - This may cause issues when you are using a cache of user objects, for example, to - improve performance in a stateless application. If the Authentication - contains a reference to an object in the cache (such as a UserDetails - instance) and this has its credentials removed, then it will no longer be possible to authenticate - against the cached value. You need to take this into account if you are using a cache. An obvious - solution is to make a copy of the object first, either in the cache implementation or in - the AuthenticationProvider which creates the returned - Authentication object. Alternatively, you can disable the - eraseCredentialsAfterAuthentication property on ProviderManager. - See the Javadoc for more information. + By default (from Spring Security 3.1 onwards) the + ProviderManager will attempt to clear any sensitive + credentials information from the Authentication + object which is returned by a successful authentication request. This prevents + information like passwords being retained longer than necessary. + This may cause issues when you are using a cache of user objects, for example, to + improve performance in a stateless application. If the + Authentication contains a reference to an object in + the cache (such as a UserDetails instance) and this + has its credentials removed, then it will no longer be possible to authenticate + against the cached value. You need to take this into account if you are using a + cache. An obvious solution is to make a copy of the object first, either in the + cache implementation or in the AuthenticationProvider + which creates the returned Authentication object. + Alternatively, you can disable the + eraseCredentialsAfterAuthentication property on + ProviderManager. See the Javadoc for more information.
@@ -107,17 +106,13 @@ - -]]> The PasswordEncoder and - SaltSource are optional. A +]]> The PasswordEncoder is optional. A PasswordEncoder provides encoding and decoding of passwords presented in the UserDetails object that is - returned from the configured UserDetailsService. A - SaltSource enables the passwords to be populated with - a "salt", which enhances the security of the passwords in the authentication - repository. These will be discussed in more detail below. + returned from the configured UserDetailsService. This + will be discussed in more detail below.
@@ -129,7 +124,8 @@ UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; - + + The returned UserDetails is an interface that provides getters that guarantee non-null provision of authentication information such as the username, password, granted authorities and whether the user account is enabled or @@ -179,7 +175,8 @@ UserDetailsService to reuse the mapping files you've probably already created. Returning to JdbcDaoImpl, an example configuration is shown below: - + @@ -190,7 +187,8 @@ - ]]> + ]]> + You can use different relational database management systems by modifying the DriverManagerDataSource shown above. You can also use a global data source obtained from JNDI, as with any other Spring configuration. @@ -219,10 +217,18 @@
Password Encoding - Spring Security's PasswordEncoder interface is used to - support the use of passwords which are encoded in some way in persistent storage. This - will normally mean that the passwords are hashed using a digest algorithm - such as MD5 or SHA. + Spring Security's + PasswordEncoder interface is used to support the use of + passwords which are encoded in some way in persistent storage. This will normally mean + that the passwords are hashed using a digest algorithm such as MD5 or + SHA. Spring Security 3.1's crypto package introduces a simpler API which encourages + best-practice for password hashing. We would encourage you to use these APIs for new + development and regard the classes in package + org.springframework.security.authentication.encoding as legacy + implementations. The DaoAuthenticationProvider can be injected + with either the new or legacy PasswordEncoder + types.
What is a hash? Password hashing is not unique to Spring Security but is a common source of @@ -232,8 +238,8 @@ the string password (in hexadecimal) is 5f4dcc3b5aa765d61d8327deb882cf99 - A hash is - one-way in the sense that it is very difficult (effectively + + A hash is one-way in the sense that it is very difficult (effectively impossible) to obtain the original input given the hash value, or indeed any possible input which would produce that hash value. This property makes hash values very useful for authentication purposes. They can be stored in your user database as @@ -254,16 +260,28 @@ salt when calculating the hashes. This is an additional string of known data for each user which is combined with the password before calculating the hash. Ideally the data should be as random as possible, but in practice any salt - value is usually preferable to none. Spring Security has a - SaltSource interface which can be used by an - authentication provider to generate a salt value for a particular user. Using a salt - means that an attacker has to build a separate dictionary of hashes for each salt - value, making the attack more complicated (but not impossible). + value is usually preferable to none. Using a salt means that an attacker has to + build a separate dictionary of hashes for each salt value, making the attack more + complicated (but not impossible). + The StandardPasswordEncoder in the crypto package uses a random 8-byte salt, which is stored + in the same field as the password. + The legacy approach to handling salt was to inject a + SaltSource into the + DaoAuthenticationProvider, which would obtain a salt + value for a particular user and pass it to the + PasswordEncoder. Using a random salt and + combining it with the password data field means you don't have to worry about + the details of salt handling (such as where the the value is stored), as it is + all done internally. So we'd strongly recommend you use this approach unless you + already have a system in place which stores the salt separately. +
Hashing and Authentication When an authentication provider (such as Spring Security's - DaoAuthenticationProvider needs to check the password in a + DaoAuthenticationProvider) needs to check the password in a submitted authentication request against the known value for a user, and the stored password is encoded in some way, then the submitted value must be encoded using exactly the same algorithm. It's up to you to check that these are compatible as @@ -274,20 +292,13 @@ example, and your application is configured to use Spring Security's Md5PasswordEncoder, there are still things that can go wrong. The database may have the passwords encoded in Base 64, for example while the - enocoder is using hexadecimal strings (the default) - You can configure the encoder to use Base 64 instead of hex by setting the - encodeHashAsBase64 property to true. Check - the Javadoc for MessageDigestPasswordEncoder and its - parent classes for more information. - . Alternatively your database may be using upper-case while the output - from the encoder is lower-case. Make sure you write a test to check the output from - your configured password encoder with a known password and salt combination and - check that it matches the database value before going further and attempting to - authenticate through your application. For more information on the default method - for merging salt and password, see the Javadoc for - BasePasswordEncoder. If you want to generate encoded - passwords directly in Java for storage in your user database, then you can use the - encodePassword method on the + encoder is using hexadecimal strings (the default). Alternatively your database may + be using upper-case while the output from the encoder is lower-case. Make sure you + write a test to check the output from your configured password encoder with a known + password and salt combination and check that it matches the database value before + going further and attempting to authenticate through your application. + If you want to generate encoded passwords directly in Java for storage in your + user database, then you can use the encode method on the PasswordEncoder.
diff --git a/docs/manual/src/docbook/crypto.xml b/docs/manual/src/docbook/crypto.xml index 7fff0ba915..e811c6aa7d 100644 --- a/docs/manual/src/docbook/crypto.xml +++ b/docs/manual/src/docbook/crypto.xml @@ -109,7 +109,7 @@ KeyGenerators.string();]]> Password Encoding The password package of the spring-security-crypto module provides support for encoding passwords. - PasswordEncoder is the central service interface and has the following signature: + PasswordEncoder is the central service interface and has the following signature: - The StandardPasswordEncoder implementation applies 1024 iterations of the SHA-256 hashing algorithm to the rawPassword combined with a site-wide secret and 8-byte random salt: + The StandardPasswordEncoder implementation applies 1024 iterations of the SHA-256 hashing algorithm to the rawPassword combined with a site-wide secret and 8-byte random salt: