-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disabling credentials erasure on custom AuthenticationManager is not working #15683
Comments
@kmartin88, thank you for reaching out!
Can you please provide more information about the security configuration and rest controller? It would be helpful if you could provide actual code, so there is no chance of misunderstanding. Currently, I am not seeing information about how you authenticate prior to calling an endpoint, and whether the endpoint you are calling is |
@sjohnr |
Thanks for the sample, @kmartin88! That does indeed help clarify your situation. I do see what the issue is so let me explain that first: Spring Security has a specific order in which it checks for beans that can be used to construct an
The reason this ordering of checks is used is historical in Spring Security, so we probably couldn't switch the order to be more intuitive or else risk breaking applications relying on this order. What I believe you are hoping for in this case based on your sample is that you fall into the third (3) case. Unfortunately, you are falling into the second (2) case because you have published a
In fact, in your sample you are using a built-in authentication mechanism (e.g. HTTP Basic or Form Login). It could be that the documentation should be modified to suggest a configuration that doesn't fall into the second case. However, I wonder if the documentation needs to be improved in some way to make this clearer or if this is simply something you missed when reading the documentation and modifying the code from there? I feel the current example and text in the docs make the use case fairly clear, but I imagine it could be confusing if the code is modified from there. Can you provide some feedback on this and whether you find the docs clear or confusing and in need of improvement? |
@sjohnr Thanks for the explanation! Even if I don't publish a UserDetailsService bean I still see the same effect in my test case. So if I do it like this:
and remove the UserDetailsService bean in the SecurityConfig, the credentials are still erased in the end. As to if I find the documentation confusing - I guess so, yes. So first it tells me I can publish an AuthenticationManager bean to be able to use it directly in a RestController.
Which sounds to me like it would be the way to go if I need to disable the credentials erasure regardless of how I use the AuthenticationManager. The following:
suggests (to me at least) that the following example is doing the same thing and both examples are interchangeable. What I really want to accomplish is (as real life examples always are) a bit more complex. We have several SecurityFilterChains and depending on a configuration file we have two authentication mechanisms out of 4 in total which should be used globally. Currently, we are doing it like this:
and this is working fine. However, when looking at several examples on how to do it since Spring Security 6, it seems to me that configuring AuthenticationManagers like this is not the intended way. |
@kmartin88 thanks for the detailed response! It appears that this documentation page is indeed inaccurate and does need to be reworked so thanks for providing this feedback. I'll use this ticket to fix the mistake.
You are good to keep the config the way you have it. That is currently the most effective way to disable credential erasure. Note: The reason the other configuration in the docs (publishing a Thanks again! |
@sjohnr Ah okay I see!
Okay this is good to know. However, if I were to say for security reasons I only want to disable credentials erasure for one of my filter chains but aside from that want to use the same authentication mechanism in all of the filter chains - how would I achieve this? The only way I can think of would be to create a new instance of a ProviderManager locally in the "unsecure" filter chain and set it directly as authenticationManager on the HttpSecurity. Like this:
So in this case, Or would there be a cleaner way without duplicating the AuthenticationManager? |
@kmartin88 glad your understanding is growing!
It feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Having said that, I think this is just a case of making your code more reusable with a factory method that creates the |
Describe the bug
In the documentation there is an example on how to customize the AuthenticationManager:
https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/index.html#customize-global-authentication-manager (below "Publish AuthenticationManager bean for Spring Security").
Even though eraseCredentialsAfterAuthentication is set to false, the credentials get erased. They seem to get erased by another ProviderManager which has an AnonymousAuthenticationProvider.
To Reproduce
Create an empty Spring Boot Project with Spring Security and Spring Web MVC, create a @RestController and a SecurityConfig like in the example. The RestController should have a method which autowires the Authentication and returns the credentials of this Authentication object. Then you call the controller with user credentials and see that the credentials are empty/null.
Expected behavior
The password of the user should be returned when calling the controller.
The text was updated successfully, but these errors were encountered: