The CredentialsContainer interface is used internally by the framework to clear the user's credentials after a successful authentication. However, there is no mention in the reference docs about this interface and whether users should implement it or not.
Comment From: PhilHYChen
If I may, I would like to offer my two cents:
-
Add a "Note" box highlighting
CredentialsContainerto "Sevlet Applications -> Authentication -> Authentication Architecture" under the second last paragraph of #ProviderManager. https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-providermanager -
Add a new "Password Erasure" item, which provides the best practice and risk assessment regarding credential erasure, next to "Password Storage" in "Servlet Applications -> Authentication -> Username/Password" in the reference doc. https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/storage.html
If the reference docs could provide a general guideline about credential erasure alongside its storage, developers could make their custom implementations with peace of mind.
-
Add
CredentialsContainerunder the previous section in the reference doc. -
In the
UserDetailsreference & API doc, recommend developers to implementCredentialsContainerif they do not utilize caching. https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/user-details.html https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetails.html
There is also another thing I'd like to mention. Though this is somewhat beyond the CredentialsContainer interface, when it comes to username/password authentication, the intended interface responsible for credential erasure (that is, if still desirable) in Spring Security seems vague.
-
Please correct me if I am missing anything, but there seems to be no interface specified to perform credential erasure. Therefore, we rely on contracts.
-
The API doc of
CredentialsContainersuggests that any customAuthenticationProviderimplementation is responsible for post-authentication credential erasure ("minus any sensitive data"). https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/CredentialsContainer.html -
Meanwhile, the API doc of
AuthenticationProviderspecifies that the methodauthenticateshould return "a fully authenticated object including credentials" without erasing them. While that adheres to the single responsibility principle, on the other hand, it seems to contradict the contract laid out inCredentialsContainer's API doc. https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/authentication/AuthenticationProvider.html
We can also look further beyond the interfaces and directly into some out-of-the-box implementations.
-
For example, the
DaoAuthenticationProviderclass. Adhering toAuthenticationProvider's contract, it does not perform credential erasure with its inheritedauthenticatemethod. https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.html#authenticate(org.springframework.security.core.Authentication) -
Instead, it relies on
ProviderManager(Spring Security's default implementation ofAuthenticationManager) to erase the credentials and other sensitive data. However, theAuthenticationManagerAPI doc states that the implementation should return "a fully authenticated object including credentials" with theauthenticatemethod. https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/authentication/ProviderManager.html
I apologize if I misunderstood the docs and the codes. I am genuinely confused here. Should either or neither my custom implementation of AuthenticationProvider or AuthenticationManager erase credentials? If I follow or deviate away from the contracts and mimic the official out-of-the-box implementations, do I risk breaking things?
Maybe it's just all a legacy thing, though if resources allow, a clean-up would probably help for better consistency.
Comment From: marcusdacoregio
Thanks for the suggestions @PhilHYChen. Would you like to provide a PR for items 1, 2, 3 and 4?
Instead, it relies on ProviderManager (Spring Security's default implementation of AuthenticationManager) to erase the credentials and other sensitive data. However, the AuthenticationManager API doc states that the implementation should return "a fully authenticated object including credentials" with the authenticate method.
I think that the information in the API doc is outdated. The AuthenticationProvider class is there since the beginning and a lot of things changed in the meantime, however the documentation wasn't updated accordingly. I believe it should just state that the method should return "a fully authenticated object".