123456789101112131415161718192021222324252627282930313233343536 |
- [[servlet-authentication-providermanager]]
- = ProviderManager
- :figures: images/servlet/authentication/architecture
- {security-api-url}org/springframework/security/authentication/ProviderManager.html[`ProviderManager`] is the most commonly used implementation of <<servlet-authentication-authenticationmanager,`AuthenticationManager`>>.
- `ProviderManager` delegates to a `List` of <<servlet-authentication-authenticationprovider,``AuthenticationProvider``s>>.
- // FIXME: link to AuthenticationProvider
- Each `AuthenticationProvider` has an opportunity to indicate that authentication should be successful, fail, or indicate it cannot make a decision and allow a downstream `AuthenticationProvider` to decide.
- If none of the configured ``AuthenticationProvider``s can authenticate, then authentication will fail with a `ProviderNotFoundException` which is a special `AuthenticationException` that indicates the `ProviderManager` was not configured to support the type of `Authentication` that was passed into it.
- image::{figures}/providermanager.png[]
- In practice each `AuthenticationProvider` knows how to perform a specific type of authentication.
- For example, one `AuthenticationProvider` might be able to validate a username/password, while another might be able to authenticate a SAML assertion.
- This allows each `AuthenticationProvider` to do a very specific type of authentication, while supporting multiple types of authentication and only exposing a single `AuthenticationManager` bean.
- `ProviderManager` also allows configuring an optional parent `AuthenticationManager` which is consulted in the event that no `AuthenticationProvider` can perform authentication.
- The parent can be any type of `AuthenticationManager`, but it is often an instance of `ProviderManager`.
- image::{figures}/providermanager-parent.png[]
- In fact, multiple `ProviderManager` instances might share the same parent `AuthenticationManager`.
- This is somewhat common in scenarios where there are multiple <<servlet-securityfilterchain,`SecurityFilterChain`>> instances that have some authentication in common (the shared parent `AuthenticationManager`), but also different authentication mechanisms (the different `ProviderManager` instances).
- image::{figures}/providermanagers-parent.png[]
- [[servlet-authentication-providermanager-erasing-credentials]]
- By default `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 in the `HttpSession`.
- 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 {security-api-url}org/springframework/security/authentication/ProviderManager.html[Javadoc] for more information.
|