Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: FusionAuth as a SAML service provider cannot connect to FusionAuth as a SAML identity provider #2979

Open
RichardJECooke opened this issue Jan 23, 2025 · 4 comments

Comments

@RichardJECooke
Copy link

RichardJECooke commented Jan 23, 2025

What happened?

Error

I write a guide detailing how to connect your website to a SAML identity provider using FusionAuth as a service provider (FusionAuth/fusionauth-site#2854). I want to use FusionAuth as the identity provider to avoid using a competitor like Dex or Keycloak in the example.

But after everything is set up, the SAML login page returns the error "message" : "OAuth return is missing the authorization code and/or the SAML encoded state.".

I've used FusionAuth as an IdP before for a website, so I know that works, but there seems to be a bug using FusionAuth as a SP connecting to FusionAuth. I've read the documentation https://fusionauth.io/docs/lifecycle/authenticate-users/identity-providers/overview-samlv2 and can't find anything I'm missing.

Details below.

Docker compose file

Below is my docker compose file. I use the host network to ensure that the error can't be caused by conflicts between localhost and fa container names differing between URLs in the browser and URLs in the server-to-server calls in the SAML protocol.

Container fa on port 9011 is the identity provider instance, and container fa2 on port 9021 is the service provider instance the website connects to.

services:
  fa_db:
    image: postgres:16.0-bookworm
    container_name: fa_db
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      PGPORT: 5432
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 5s
      timeout: 5s
      retries: 5
    network_mode: host
    platform: linux/amd64
    volumes:
      - db_data:/var/lib/postgresql/data

  fa_db2:
    image: postgres:16.0-bookworm
    container_name: fa_db2
    platform: linux/amd64
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      PGPORT: 5433
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 5s
      timeout: 5s
      retries: 5
    network_mode: host
    volumes:
      - db_data2:/var/lib/postgresql/data

  fa:
    image: fusionauth/fusionauth-app:1.54.0
    container_name: fa
    platform: linux/amd64
    depends_on:
      fa_db:
        condition: service_healthy
    environment:
      DATABASE_URL: jdbc:postgresql://localhost:5432/fusionauth
      DATABASE_ROOT_USERNAME: ${POSTGRES_USER}
      DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
      DATABASE_USERNAME: ${DATABASE_USERNAME}
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY}
      FUSIONAUTH_APP_RUNTIME_MODE: development
      FUSIONAUTH_APP_URL: http://localhost:9011
      FUSIONAUTH_APP_HTTP_PORT: 9011
      FUSIONAUTH_APP_HTTP_LOCAL_PORT: 9012
      SEARCH_TYPE: database
      FUSIONAUTH_APP_KICKSTART_FILE: ${FUSIONAUTH_APP_KICKSTART_FILE}
    network_mode: host
    volumes:
      - fusionauth_config:/usr/local/fusionauth/config
      - ./kickstart:/usr/local/fusionauth/kickstart

  fa2:
    image: fusionauth/fusionauth-app:1.54.0
    container_name: fa2
    platform: linux/amd64
    depends_on:
      fa_db2:
        condition: service_healthy
    environment:
      DATABASE_URL: jdbc:postgresql://localhost:5433/fusionauth
      DATABASE_ROOT_USERNAME: ${POSTGRES_USER}
      DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
      DATABASE_USERNAME: ${DATABASE_USERNAME}
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      FUSIONAUTH_APP_MEMORY: ${FUSIONAUTH_APP_MEMORY}
      FUSIONAUTH_APP_RUNTIME_MODE: development
      FUSIONAUTH_APP_URL: http://localhost:9021
      FUSIONAUTH_APP_HTTP_PORT: 9021
      FUSIONAUTH_APP_HTTP_LOCAL_PORT: 9022
      SEARCH_TYPE: database
      FUSIONAUTH_APP_KICKSTART_FILE: ${FUSIONAUTH_APP_KICKSTART_FILE}
    network_mode: host
    volumes:
      - fusionauth_config2:/usr/local/fusionauth/config
      - ./kickstart:/usr/local/fusionauth/kickstart

volumes:
  db_data:
    name: db_data
  fusionauth_config:
    name: fusionauth_config
  db_data2:
    name: db_data2
  fusionauth_config2:
    name: fusionauth_config2

The env and kickstart files come from the standard quickstart: https://github.com/fusionauth/fusionauth-example-docker-compose/blob/main/light/kickstart/kickstart.json

Setup instructions

Error: "message" : "OAuth return is missing the authorization code and/or the SAML encoded state."

URL: http://localhost:9011/samlv2/callback/d7d09513-a3f5-401c-9685-34ab6c552453?error=invalid_request&error_reason=invalid_origin&error_description=Invalid+origin+uri+http%3A%2F%2Flocalhost%3A9021&state=eyJ...

Event log from IdP:

Incoming SAML v2 AuthnRequest.

Binding:
urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect

Deflated and encoded request:
fZLdatwwEIVfxajXtmRJXtvCdlgSAgtpKfm76J1WlncNsrTVyOvm7StvmwYK2dvhzDkz30xz82syyVl7GJ1tUZ4RlGirXD/aQ4tenu/TCiUQpO2lcVa36E0DuukaC0xs53C0j/rnrCEk0cZCi2ZvhZMwgrBy0iCCEk/brw+CZkRIAO1DzEF/1MICbdExhJPAeFmWbGGZ8wdMCSGY1DiKehgPXz7k7HrAybvglDMfDfwT/xwTvvrHVaP99n2wW2dhnrR/0v48Kv3y+PCv3zglzdFBEDWhOQY5mTPFUgFKdnctGvt92e95wUtJqpIP5aYuKtkztqlKytlec5S8vlOmK+UdwKx3dmUbYonQIiV5StlzTkRRC8azivEfqGsuQt9dnQNOeEOHutKkTxktacpjdlpLRVNd8CHnWu2rmjb4r9nlft8iwN3dd2dG9ZbcOz/JcJ3vWhn7dLhIxWldB4K2IRI0xi23XssQX2SQBjTCXYP//5LuNw==

Decoded XML request:
<?xml version="1.0" encoding="UTF-8"?><ns3:AuthnRequest xmlns:ns3="urn:oasis:names:tc:SAML:2.0:protocol" xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns4="http://www.w3.org/2001/04/xmlenc#" AssertionConsumerServiceURL="http://localhost:9021/samlv2/acs" ID="idb7db4547a0874f76958ad33687243be4" Version="2.0" IssueInstant="2025-01-23T10:59:34.834Z">
  <Issuer>http://localhost:9021/samlv2/sp/62f98e0d-3272-4ad3-9ac2-e54f14ecb892</Issuer>
  <ns3:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" AllowCreate="false"/>
</ns3:AuthnRequest>

Event log from SP:

SAML v2 IdP AuthN Request Debug Log for [fa] [62f98e0d-3272-4ad3-9ac2-e54f14ecb892]

1/23/2025 10:59:34 AM Z Build the AuthN SAML v2 request.
1/23/2025 10:59:34 AM Z Begin AuthN request by calling /api/identity-provider/start to register a SAML v2 request Id.
1/23/2025 10:59:34 AM Z Start request returned request Id [idb7db4547a0874f76958ad33687243be4]
1/23/2025 10:59:34 AM Z AuthN request being sent to the identity provider.
1/23/2025 10:59:34 AM Z http://localhost:9011/samlv2/login/d7d09513-a3f5-401c-9685-34ab6c552453
1/23/2025 10:59:34 AM Z Binding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
1/23/2025 10:59:34 AM Z Query string: SAMLRequest=fZLdatwwEIVfxajXtmRJXtvCdlgSAgtpKfm76J1WlncNsrTVyOvm7StvmwYK2dvhzDkz30xz82syyVl7GJ1tUZ4RlGirXD%2FaQ4tenu%2FTCiUQpO2lcVa36E0DuukaC0xs53C0j%2FrnrCEk0cZCi2ZvhZMwgrBy0iCCEk%2Fbrw%2BCZkRIAO1DzEF%2F1MICbdExhJPAeFmWbGGZ8wdMCSGY1DiKehgPXz7k7HrAybvglDMfDfwT%2FxwTvvrHVaP99n2wW2dhnrR%2F0v48Kv3y%2BPCv3zglzdFBEDWhOQY5mTPFUgFKdnctGvt92e95wUtJqpIP5aYuKtkztqlKytlec5S8vlOmK%2BUdwKx3dmUbYonQIiV5StlzTkRRC8azivEfqGsuQt9dnQNOeEOHutKkTxktacpjdlpLRVNd8CHnWu2rmjb4r9nlft8iwN3dd2dG9ZbcOz%2FJcJ3vWhn7dLhIxWldB4K2IRI0xi23XssQX2SQBjTCXYP%2F%2F5LuNw%3D%3D&RelayState=Y2xpZW50X2lkPWU5ZmRiOTg1LTkxNzMtNGUwMS05ZDczLWFjMmQ2MGQxZGM4ZSZjb2RlX2NoYWxsZW5nZT0mY29kZV9jaGFsbGVuZ2VfbWV0aG9kPSZtZXRhRGF0YS5kZXZpY2UubmFtZT1MaW51eCUyMENocm9tZSZtZXRhRGF0YS5kZXZpY2UudHlwZT1CUk9XU0VSJm5vbmNlPSZyZWRpcmVjdF91cmk9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZhdXRoJTJGY2FsbGJhY2smcmVzcG9uc2VfbW9kZT0mcmVzcG9uc2VfdHlwZT1jb2RlJnNjb3BlPW9wZW5pZCUyMGVtYWlsJTIwcHJvZmlsZSUyMG9mZmxpbmVfYWNjZXNzJnN0YXRlPSZ0ZW5hbnRJZD1kN2QwOTUxMy1hM2Y1LTQwMWMtOTY4NS0zNGFiNmM1NTI0NTMmdGltZXpvbmU9QWZyaWNhJTJGSm9oYW5uZXNidXJnJnVzZXJfY29kZT0mY3NyZj10SnotVzF6MWhQYUJxQ2ZLJnJlbWVtYmVyRGV2aWNlPWZhbHNlJmlkZW50aXR5UHJvdmlkZXJJZD02MmY5OGUwZC0zMjcyLTRhZDMtOWFjMi1lNTRmMTRlY2I4OTI
1/23/2025 10:59:34 AM Z Deflated and encoded request: 
fZLdatwwEIVfxajXtmRJXtvCdlgSAgtpKfm76J1WlncNsrTVyOvm7StvmwYK2dvhzDkz30xz82syyVl7GJ1tUZ4RlGirXD/aQ4tenu/TCiUQpO2lcVa36E0DuukaC0xs53C0j/rnrCEk0cZCi2ZvhZMwgrBy0iCCEk/brw+CZkRIAO1DzEF/1MICbdExhJPAeFmWbGGZ8wdMCSGY1DiKehgPXz7k7HrAybvglDMfDfwT/xwTvvrHVaP99n2wW2dhnrR/0v48Kv3y+PCv3zglzdFBEDWhOQY5mTPFUgFKdnctGvt92e95wUtJqpIP5aYuKtkztqlKytlec5S8vlOmK+UdwKx3dmUbYonQIiV5StlzTkRRC8azivEfqGsuQt9dnQNOeEOHutKkTxktacpjdlpLRVNd8CHnWu2rmjb4r9nlft8iwN3dd2dG9ZbcOz/JcJ3vWhn7dLhIxWldB4K2IRI0xi23XssQX2SQBjTCXYP//5LuNw==
1/23/2025 10:59:34 AM Z Relay state: 
Y2xpZW50X2lkPWU5ZmRiOTg1LTkxNzMtNGUwMS05ZDczLWFjMmQ2MGQxZGM4ZSZjb2RlX2NoYWxsZW5nZT0mY29kZV9jaGFsbGVuZ2VfbWV0aG9kPSZtZXRhRGF0YS5kZXZpY2UubmFtZT1MaW51eCUyMENocm9tZSZtZXRhRGF0YS5kZXZpY2UudHlwZT1CUk9XU0VSJm5vbmNlPSZyZWRpcmVjdF91cmk9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZhdXRoJTJGY2FsbGJhY2smcmVzcG9uc2VfbW9kZT0mcmVzcG9uc2VfdHlwZT1jb2RlJnNjb3BlPW9wZW5pZCUyMGVtYWlsJTIwcHJvZmlsZSUyMG9mZmxpbmVfYWNjZXNzJnN0YXRlPSZ0ZW5hbnRJZD1kN2QwOTUxMy1hM2Y1LTQwMWMtOTY4NS0zNGFiNmM1NTI0NTMmdGltZXpvbmU9QWZyaWNhJTJGSm9oYW5uZXNidXJnJnVzZXJfY29kZT0mY3NyZj10SnotVzF6MWhQYUJxQ2ZLJnJlbWVtYmVyRGV2aWNlPWZhbHNlJmlkZW50aXR5UHJvdmlkZXJJZD02MmY5OGUwZC0zMjcyLTRhZDMtOWFjMi1lNTRmMTRlY2I4OTI
1/23/2025 10:59:34 AM Z Un-encoded XML request:<?xml version="1.0" encoding="UTF-8"?><ns3:AuthnRequest xmlns:ns3="urn:oasis:names:tc:SAML:2.0:protocol" xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns4="http://www.w3.org/2001/04/xmlenc#" AssertionConsumerServiceURL="http://localhost:9021/samlv2/acs" ID="idb7db4547a0874f76958ad33687243be4" Version="2.0" IssueInstant="2025-01-23T10:59:34.834Z">
  <Issuer>http://localhost:9021/samlv2/sp/62f98e0d-3272-4ad3-9ac2-e54f14ecb892</Issuer>
  <ns3:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" AllowCreate="false"/>
</ns3:AuthnRequest>

Version

1.54.0

Affects Versions

No response

@RichardJECooke
Copy link
Author

Maybe related to #119 ?

@RichardJECooke
Copy link
Author

I get the same error when trying to use FA on localhost as the SP and FA Cloud as the IdP.

URL: https://fusionauthdemo.fusionauth.io/samlv2/callback/38793cd1-27cb-10b3-c693-ba9f0a809152?error=invalid_request&error_reason=invalid_origin&error_description=Invalid+origin+uri+http%3A%2F%2Flocalhost%3A9021&state=eyJ...

Error: { "message" : "OAuth return is missing the authorization code and/or the SAML encoded state." }

@RichardJECooke
Copy link
Author

Using Okta as the Idp works fine, so I'll use that in the guide. When this FusionAuth bug is fixed I'll update the guide to make it easier to complete without needing a whole 3rd party web app with mobile authentication codes.

@RichardJECooke
Copy link
Author

Article will be located at /docs/lifecycle/examples/authenticate-users-with-saml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant