tryingToLearn
tryingToLearn

Reputation: 11663

How to modify Spring Security filter chain at runtime?

I am using Spring security and my config looks like this. I am using Spring Security SAML library.

http
    .addFilterBefore(metadataGeneratorFilter(samlEntryPoint, extendedMetadata), ChannelProcessingFilter.class)
    .addFilterAfter(samlFilter(samlEntryPoint, contextProvider), BasicAuthenticationFilter.class)
    .authenticationProvider(samlAuthenticationProvider);

private FilterChainProxy samlFilter(SAMLEntryPoint samlEntryPoint, SAMLContextProvider contextProvider) {
        List<SecurityFilterChain> chains = new ArrayList<>();
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
            samlEntryPoint));
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
            new MetadataDisplayFilter()));
        try {
            chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
                samlWebSSOProcessingFilter(samlAuthenticationProvider, contextProvider, samlProcessor)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        SAMLDiscovery samlDiscovery = new SAMLDiscovery();
        samlDiscovery.setMetadata(cachingMetadataManager);
        samlDiscovery.setContextProvider(contextProvider);
        chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"),
            samlDiscovery));
        return new FilterChainProxy(chains);
    }

Now since my app supports dynamic configuration, if the IDP SSO url is changed from /saml/SSO to something else, then following filter will not work as the url is hardcoded and the configuration will take effect only after server restart.

chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
                    samlWebSSOProcessingFilter(samlAuthenticationProvider, contextProvider, samlProcessor)));

Is there a way to change the filter at runtime? I can see the getRequestMatcher() method in Official Spring docs but no way to set it. Am I approaching the problem in a wrong way?

Upvotes: 1

Views: 2815

Answers (1)

Adam Zhang
Adam Zhang

Reputation: 96

I think you can implement a customized RequestMatcher to check the url:

public class CustomizedAntRequestMatcher implements RequestMatcher {
    @Override
    public boolean matches(HttpServletRequest request) {
        String url = "/saml/SSO/**"; //change this line to get your dynamic configuration
        AntPathRequestMatcher antPathRequestMatcher = new AntPathRequestMatcher(url);
        return antPathRequestMatcher.matches(request);
    }
}

And then use the customized request matcher to replace the AntPathRequestMatcher:

chains.add(new DefaultSecurityFilterChain(new CustomizedRequestMatcher(),
                    samlWebSSOProcessingFilter(samlAuthenticationProvider, contextProvider, samlProcessor)));

Contact me if this way can not resolve your problem.

Upvotes: 2

Related Questions