Document the role of `CredentialsContainer`
marcusdacoregio opened this issue · comments
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.
If I may, I would like to offer my two cents:
-
Add a "Note" box highlighting
CredentialsContainer
to "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
CredentialsContainer
under the previous section in the reference doc. -
In the
UserDetails
reference & API doc, recommend developers to implementCredentialsContainer
if 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
CredentialsContainer
suggests that any customAuthenticationProvider
implementation 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
AuthenticationProvider
specifies that the methodauthenticate
should 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
DaoAuthenticationProvider
class. Adhering toAuthenticationProvider
's contract, it does not perform credential erasure with its inheritedauthenticate
method.
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, theAuthenticationManager
API doc states that the implementation should return "a fully authenticated object including credentials" with theauthenticate
method.
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.
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".