Describe the bug
The BasicAuthenticationFilter skips re-authentication if the username changes in the basic authentication header and the Authentication object is not an instance of UsernamePasswordAuthenticationToken.
The BasicAuthenticationFilter contains an authenticationIsRequired method that is private and so cannot be overridden to add handling for different Authentication object types that may support UsernamePasswordAuthenticationToken style authentication, but do not inherit from the UsernamePasswordAuthenticationToken.
We have an Authentication class that is a wrapper around existing authentication instances to allow us to provide MFA functionality after the Basic Authentication mechanism succeeds.
To Reproduce
- Configure Spring Security with a custom authentication provider that wraps the
UsernamePasswordAuthenticationTokenas a delegate. - Login with basic auth and maintain a session so the existing authentication is stored
- Send a second request for the same session with different basic auth credentials and the
authenticationIsRequiredcheck is skipped and you carry on with the original user auth.
Expected behaviour
The BasicAuthenticationFilter should allow the authenticationIsRequired method to be overridden to allow additional checks for different Authentication types that support username/password but that cannot inherit from UsernamePasswordAuthenticationToken, to allow this SEC-348 security check to be performed.
For security reasons we should not have to clone the BasicAuthenticationFilter to achieve this.
Sample
To Follow
Comment From: jzheaux
Given that this check was added for CAS and the CAS module is removed in 6.0.x, is the existingAuth instanceof UsernamePasswordAuthenticationToken check something that can also be removed in 6.0.x, @rwinch?
Or, if we leave it in, comparing it against a concrete Authentication type seems less flexible than comparing against an Authentication#getPrincipal interface type.
Comment From: rwinch
I think this can be removed for 6.0.x since CAS has been removed. It's important to note that the CAS code probably should have had a custom Authentication type rather than try to reuse UsernamePasswordAuthenticationToken.