Expected Behavior
As I understand AuthenticationManager is meant to be the main entity to manage core authentication process, i.e. to provide an Authentication object. I would expect that in particular, it has the authority to exchange (incl. its type) the Authentication object returned by the AuthenticationProviders.
Current Behavior
The OAuth2LoginAuthenticationFilter offers a way to customize the AuthenticationManager it uses via OAuth2LoginConfigurer which is fine. However, with the current design of the filter, it places a strong assumption on the AuthenticationManager, that it will return an Authentication of type OAuth2LoginAuthenticationToken (cast in OAuth2LoginAuthenticationFilter.attemptAuthentication()). This deprives the AuthenticationManager authority to e.g. wrap the Authentication object returned by providers into a new of different type. In that way the filter becomes in fact an uber-AuthenticationManager.
Context
Use case: replace the GrantedAuthorities during business context change (e.g. in multi-tenant applications). As the GrantedAuthorities are part of Authentication object, the only way to replace them, without resorting to recreating the Token (which introduces high level of coupling into the specific AuthenticationProvider details) - is to wrap the Authentication object into a custom one. Additional context is that the scenario should work for various authentication schemes (another argument against Token re-creation).
My current workaround is to use the OAuth2LoginConfigurer.successHandler() to replace the object within SecurityContext, but I recognize this is OAuth2LoginConfigurer-specific, which de-facto drives into using similar specific workarounds for other authentication schemes in place, as a general solution with AuthenticationManager cannot be used.