spring-attic / spring-security-saml

SAML extension for the Spring Security project
Other
419 stars 482 forks source link

HostedServiceProviderService#authenticationRequest has invalid cast method. #469

Closed kenchan0130 closed 4 years ago

kenchan0130 commented 4 years ago

When I use a properties file like:

# application.properites

spring.security.saml2.network.read-timeout=10000
spring.security.saml2.network.connect-timeout=5000
spring.security.saml2.service-provider.entity-id=test
spring.security.saml2.service-provider.alias=test
spring.security.saml2.service-provider.base-path=http://localhost:8081
spring.security.saml2.service-provider.sign-metadata=false
spring.security.saml2.service-provider.sign-requests=false
spring.security.saml2.service-provider.want-assertions-signed=false
spring.security.saml2.service-provider.single-logout-enabled=true
spring.security.saml2.service-provider.keys.active.name=spring
spring.security.saml2.service-provider.keys.active.passphrase=secret
spring.security.saml2.service-provider.keys.active.certificate=MIIDdzCCAl+gAwIBAgIEF6unJTANBgkqhkiG9w0BAQsFADBsMRAwDgYDVQQGEwdV\
bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD\
VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du\
MB4XDTE4MDQyNjA4MTE1NloXDTQ1MDkxMTA4MTE1NlowbDEQMA4GA1UEBhMHVW5r\
bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE\
ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC\
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpDwL3nsRf7zisRb5gzw4Ia\
i6tOAR3aMJDx/c4pVCkk3mXr3nHi88BSNWa6mhK7uwPcuBJCWJlBuPjB+zjCGxq7\
GzQae7oxXRTsPL2SscFX2l9Sk9je8vFoo8EsFZMj0isw/lj2W9p4zbtkWUy8xU1I\
NnlfECNSicB6UeqcsRwhHPQtmocmddGcfd7D9SpP4+YrdEFK18v24GurLnem2vKl\
zIJGZV1SYPvWjcwDpOuR6Yc7Q+UA9jWh/A/Qb7sDG19uM6ndll2u7+9zzlUepiXB\
+f30NhjjXlPtTOGYiegoIfFmAJawj25p7h/fXwYz+gVfOExQF5X13EVaI4eaSWkC\
AwEAAaMhMB8wHQYDVR0OBBYEFPH6nXVDVT1HS3xc1/iBiAgl6lvZMA0GCSqGSIb3\
DQEBCwUAA4IBAQBijy0KA3+pM+8hUklVMRRX2ZuZ3y8KrY7TeHeWQd88fyM0AjTP\
GyND6r5JsCBZJqiC6HgycEup6TL5L9NfpNuNOQi19ouAjvrLWDygpJW9zqrVyWqz\
Pnrl5H+6NSvd1pjWLGUwqisAKBPlIFWmWN2Z3ouDqc1rwgF4KZrjLW3v/+yILdjb\
lVR0r8o70ynOiUB2VN/7WX2a6MuBXv3JiPiyhqFdWFhcRWphZjo4Yh8dApj79d15\
MXI5uAm5K7ZHZsWFNvjnwxuhWwDURldvqL1VuChxD4hgfXO4t+oDQMQDa5tn6Ov5\
68aQRwURcoufrRJ6R0drTEQueJszi6FVx5Ld
spring.security.saml2.service-provider.providers[0].alias=simpleSAMLphp
spring.security.saml2.service-provider.providers[0].metadata=http://localhost:8080/simplesaml/saml2/idp/metadata.php
spring.security.saml2.service-provider.providers[0].authentication-request-binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
spring.security.saml2.service-provider.providers[0].skip-ssl-validation=true
spring.security.saml2.service-provider.providers[0].assertion-consumer-service-index=0

The following error occurs.

java.lang.ClassCastException: org.springframework.security.saml.provider.config.ExternalProviderConfiguration cannot be cast to org.springframework.security.saml.provider.service.config.ExternalIdentityProviderConfiguration
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
    at java.util.LinkedList$LLSpliterator.tryAdvance(LinkedList.java:1249)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
    at org.springframework.security.saml.provider.service.HostedServiceProviderService.getIdentityProviderConfigurationForMetadata(HostedServiceProviderService.java:190)
    at org.springframework.security.saml.provider.service.HostedServiceProviderService.authenticationRequest(HostedServiceProviderService.java:136)
    at org.springframework.security.saml.provider.service.SamlAuthenticationRequestFilter.getAuthenticationRequest(SamlAuthenticationRequestFilter.java:96)
    at org.springframework.security.saml.provider.service.SamlAuthenticationRequestFilter.doFilterInternal(SamlAuthenticationRequestFilter.java:79)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.saml.provider.SamlMetadataFilter.doFilterInternal(SamlMetadataFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.saml.provider.config.ThreadLocalSamlConfigurationFilter.doFilterInternal(ThreadLocalSamlConfigurationFilter.java:42)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

Workaround

We can temporarily avoid this problem by defining a separate config that inherits from SamlServiceProviderServerBeanConfiguration.

@Configuration
public class SamlServerBeanConfiguration extends SamlServiceProviderServerBeanConfiguration {
    @Value("${spring.security.saml2.service-provider.providers[0].metadata}")
    String metadata;

    @Value("${spring.security.saml2.service-provider.providers[0].alias}")
    String alias;

    @Value("${spring.security.saml2.service-provider.providers[0].authentication-request-binding}")
    String authenticationRequestBinding;

    @Value("${spring.security.saml2.service-provider.providers[0].skip-ssl-validation}")
    boolean skipSslValidation;

    @Value("${spring.security.saml2.service-provider.providers[0].assertion-consumer-service-index}")
    int assertionConsumerServiceIndex;

    private final SamlSecurityConfiguration config;

    @Override
    protected SamlServerConfiguration getDefaultHostSamlServerConfiguration() {
        List<ExternalIdentityProviderConfiguration> providers = new ArrayList<>();
        providers.add(externalProvider());
        config.getServiceProvider().setProviders(providers);
        return config;
    }

    public SamlServerBeanConfiguration(SamlSecurityConfiguration config) {
        this.config = config;
    }

    private ExternalIdentityProviderConfiguration externalProvider() {
        final ExternalIdentityProviderConfiguration externalIdentityProviderConfiguration = new ExternalIdentityProviderConfiguration();
        return externalIdentityProviderConfiguration
                .setMetadata(metadata)
                .setAlias(alias)
                .setSkipSslValidation(skipSslValidation)
                .setAuthenticationRequestBinding(URI.create(authenticationRequestBinding))
                .setAssertionConsumerServiceIndex(assertionConsumerServiceIndex);
    }
}

Environment

OS: Mac OS X OS version: 10.14.6 org.springframework.boot: 1.5.10.RELEASE spring-security-saml2-core: 2.0.0.M30 JDK: Amazon 8.0.212-amzn

yellapusony229 commented 4 years ago

Is there any way that I can skip the IDP selection filter? I have configured only one IDP provider, but still it is redirecting to saml/select page. can you please suggest on this.

jzheaux commented 4 years ago

@kenchan0130 I'm glad you found a workaround.

Since active development of Spring Security SAML has moved over to Spring Security proper, no further work is anticipated on this ticket, but I think the information here is still helpful for those using the 2.x milestones.