15

Usually my Spring SAML-based Service Provider (SP) implementation works fine, but sometimes it returns this error:

[2014-07-17 16:00:58.767] boot - 1078 DEBUG [http-bio-80-exec-1] --- BaseMessageDecoder:     Successfully decoded message.
[2014-07-17 16:00:58.767] boot - 1078 DEBUG [http-bio-80-exec-1] --- BaseSAMLMessageDecoder: Checking SAML message intended destination endpoint against receiver endpoint
[2014-07-17 16:00:58.768] boot - 1078 DEBUG [http-bio-80-exec-1] --- BaseSAMLMessageDecoder: Intended message destination endpoint: https://prismasp.cloud.reply.eu:443/MIUR_PRISMA-2.1-WEBUI/saml/SSO/alias/defaultAlias
[2014-07-17 16:00:58.768] boot - 1078 DEBUG [http-bio-80-exec-1] --- BaseSAMLMessageDecoder: Actual message receiver endpoint: http://prismasp.cloud.reply.eu:443/MIUR_PRISMA-2.1-WEBUI/saml/SSO/alias/defaultAlias
[2014-07-17 16:00:58.768] boot - 1078 ERROR [http-bio-80-exec-1] --- BaseSAMLMessageDecoder: SAML message intended destination endpoint 'https://prismasp.cloud.reply.eu:443/MIUR_PRISMA-2.1-WEBUI/saml/SSO/alias/defaultAlias' did not match the recipient endpoint 'http://prismasp.cloud.reply.eu:443/MIUR_PRISMA-2.1-WEBUI/saml/SSO/alias/defaultAlias'
[2014-07-17 16:00:58.782] boot - 1078 DEBUG [http-bio-80-exec-1] --- SAMLProcessingFilter: Incoming SAML message is invalid
org.opensaml.xml.security.SecurityException: SAML message intended destination endpoint did not match recipient endpoint
...

I'm using (as default setting of Spring Security) the HTTP Strict Transport Security (HSTS) on Tomcat 7 with SSL enabled.

Is there a way to fix this error?


Note: sample source code is on Github: vdenotaris/spring-boot-security-saml-sample.

vdenotaris
  • 11,848
  • 23
  • 69
  • 121
  • I think you missed the 's' in the protocol configured in your idp endpoint. You expect "https" but it seems that you receive "http". – alain.janinm Jul 17 '14 at 14:15
  • The current configuration works usually fine, just sometimes it causes the error as above. I'm thinking that the problem is something else. Maybe I've to setup manually the metadata, maybe I've missed a certain setting (I'm just supposing). – vdenotaris Jul 17 '14 at 14:29
  • The link gives me a "Whitelabel Error Page". It's not a metadata. Also, that's wired when you say "works usually fine", it should always or never works ! I guess there is something to do with the protocol. Maybe sometimes you connect from http and sometimes from https. And your idp seems to expect https. – alain.janinm Jul 17 '14 at 14:52
  • There was just a "7" instead of "/" – vdenotaris Jul 17 '14 at 20:48

3 Answers3

29

I don't know why is your problem occurring randomly, but at least one way to fix it is by configuring SAMLContextProviderLB instead of your current SAMLContextProviderImpl.

The SAMLContextProviderLB is typically used to tell Spring SAML public about the public URL used on a reverse proxy or load balancer, but in this case you can use to force Spring SAML to think it's using HTTPS. You can find details in chapter 10.1 Advanced Configuration of the Spring SAML manual.

You should also make sure to properly set property entityBaseURL on your MetadataGenerator bean, because without doing so the generated metadata will depend on whether you made first request to your application using http or https. Again, all of this is documented.

Desislav Kamenov
  • 1,155
  • 6
  • 13
Vladimír Schäfer
  • 14,559
  • 2
  • 45
  • 65
  • you can also use a `TLSProtocolConfigurer`, see: https://docs.spring.io/spring-security-saml/docs/2.0.x/reference/htmlsingle/#configuration-metadata-https – Gregor Nov 06 '18 at 10:31
4

I had the same problem with Spring Security SAML. So i had to change the contextProvider from SAMLContextProviderImpl:

  @Bean
  public SAMLContextProviderImpl contextProvider() {
      return new SAMLContextProviderImpl();
  }

to SAMLContextProviderLB:

  @Bean
  public SAMLContextProviderLB contextProvider() {
    SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
    samlContextProviderLB.setScheme(scheme);
    samlContextProviderLB.setServerName(serverName);
    samlContextProviderLB.setContextPath(contextPath);
      return samlContextProviderLB;
  }
0

I think your Application Server is behind a load balancer!.

For Apache Tomcat server, which is running behind AWS Application load balancer, need to enable the RemoteIPValue so that based on the x-forwarded-proto header, Tomcat will overwrite scheme(https) & port(443) accordingly.

In server.xml

<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" internalProxies="10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|169\.254\.\d+\.\d+|127\.\d+\.\d+\.\d+|172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+" />
Velu
  • 1,075
  • 14
  • 22