Need to add support for retrieving tokens from different headers in one component. This is a common case when a project has multiple authentication schemes. For example, in ProviderManager there are two providers, but one gets the token through DefaultBearerTokenResolver and the other from a non-standard header like -X-Authorization. For example, component DelegatingBearerTokenResolver:

    @Override
    public String resolve(HttpServletRequest request) {
        return delegates.stream()
                .map(d -> d.resolve(request))
                .filter(Objects::nonNull)
                .findAny()
                .orElse(null);
    }

Comment From: franticticktick

It also makes sense to make a DelegatingServerAuthenticationConverter for different authentication schemes. What’s interesting is there is no way to change the authorizationPattern in the ServerBearerTokenAuthenticationConverter, which prevents this component from being used for non-standard authentication schemes.

Comment From: jzheaux

I think a DelegatingServerAuthenticationConverter would be nice, @CrazyParanoid. Can you submit a PR for it?

Comment From: franticticktick

Added DelegatingBearerTokenResolver. I see that DelegatingServerAuthenticationConverter was added in another PR.

Comment From: jzheaux

I'm reopening this since there is more to discuss to address the servlet side of this enhancement.

Comment From: jzheaux

I don't prefer to add a delegating bearer token resolver as the use case is quite narrow. Instead, I'd prefer to add DelegatingAuthenticationConverter so that it can service more use cases. If you are interested a PR is welcome.

I realize that BearerTokenAuthenticationFilter doesn't use AuthenticationConverter currently, so that doesn't address your concern directly. I believe https://github.com/spring-projects/spring-security/issues/11983 will. In the meantime, you can do:

@Bean 
BearerTokenResolver bearerTokenResolver() {
    BearerTokenResolver one = ...;
    BearerTokenResolver two = ...;
    return (request) -> Optional.ofNullable(one.resolve(request)).orElseGet(() -> two.resolve(request));
}

Comment From: franticticktick

Hi @jzheaux. Thanks for your feedback! I added support DelegatingAuthenticationConverter to my PR.

Comment From: franticticktick

@jzheaux if the AuthenticationFilter is going to be placed in the configurer, maybe it would be worth implementing a BearerTokenAuthenticationConverter? In this case, in the configurer you can implement:

    @Override
    public void configure(H http) {
        AuthenticationManagerResolver resolver = this.authenticationManagerResolver;
        if (resolver == null) {
            AuthenticationManager authenticationManager = getAuthenticationManager(http);
            resolver = (request) -> authenticationManager;
        }

        BearerTokenAuthenticationConverter converter = new BearerTokenAuthenticationConverter();

        AuthenticationFilter filter = new AuthenticationFilter(resolver, converter);
        filter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
        filter = postProcess(filter);
        http.addFilter(filter);
    }

Comment From: jzheaux

@CrazyParanoid, I think it is worth looking into so long as https://github.com/spring-projects/spring-security/issues/9576 is not regressed. Will you please open a separate ticket for now, now that this ticket because the work for adding delegating authentication converters?