docs icon indicating copy to clipboard operation
docs copied to clipboard

Discrepancy in documentation of SAML config

Open drpdishant opened this issue 2 years ago • 5 comments

Describe the Bug

I have configured Directus with SAML SSO with Okta The auth flow is initiated from Directus but throws unexpected error upon receiving SAML Response Error:

[06:44:05.272] WARN: [SAML] Unexpected error during SAML login
directus    |     err: {
directus    |       "type": "TypeError",
directus    |       "message": "Cannot read properties of undefined (reading 'toLowerCase')",
directus    |       "stack":
directus    |           TypeError: Cannot read properties of undefined (reading 'toLowerCase')
directus    |               at SAMLAuthDriver.fetchUserID (file:///directus/node_modules/.pnpm/file+api/node_modules/@directus/api/dist/auth/drivers/saml.js:36:75)
directus    |               at SAMLAuthDriver.getUserID (file:///directus/node_modules/.pnpm/file+api/node_modules/@directus/api/dist/auth/drivers/saml.js:44:35)
directus    |               at AuthenticationService.login (file:///directus/node_modules/.pnpm/file+api/node_modules/@directus/api/dist/services/authentication.js:43:37)
directus    |               at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
directus    |               at async file:///directus/node_modules/.pnpm/file+api/node_modules/@directus/api/dist/auth/drivers/saml.js:114:60
directus    |     }

Following is the Content of SAML Response:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://directus.192.168.29.216.nip.io/auth/login/sso/acs" ID="id10163046429617805585028950" InResponseTo="_a5e37f1a-171f-4b89-b097-e4aa1a5c46af" IssueInstant="2023-08-09T06:44:02.093Z" Version="2.0">
  <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/exk91vwiyk0PeANC25d7</saml2:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
      <ds:Reference URI="#id10163046429617805585028950">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
        <ds:DigestValue>HEI77t+IuSL/yWFDtYZMhcVO2njjHNQ4anv6wUBsEyA=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>k1rt1oCpMqBm8j8OCC5k46Fd8hNa2OCT5TvvVt/pryvvyh370MEUjtmXnbskMBMfbfGz1MDvEK1lqs30UljHSJn9DFMnqUMxJs+xDDPDjpbtTATxPgZfyjK2IuCAoDgBsWAUf0VEiNAgsy/g5HPkKF0qedfhX9RMO0Eyei6lMSJen5beHwi3Bgn1aUvTO/ZfuYgGn7U8zWHYVffeyvulQu37qbSyFMEmwgCY9F8rnzrqvwVrYdcQBbPcHAmFtqJFFuoogHHXxLKoMlhd689nqA7a0HeoTGhlnIgATNJ38k9YEG214rdAP4NYL1OK4z1smd5uzVlPu5lTmS2j49VF5g==</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>MIIDqDCCApCgAwIBAgIGAYdpe5zzMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA0MTAwNDQ0MjFaFw0zMzA0MTAwNDQ1MjFaMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEc
MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAKA4byPf3iEgVEL3NHfhZYCd6izBNa8lkmbT5ImHyjEJfqw0fTocmQRb5Nn3G3pg6MoX8yYG
v2wfcyXDt67Fio5vDsJ7BjxhmL13TuD/S2jUAX0qRgXrO40xlzkteoanWZSxbjQATKcp30VhkZS+
RYWuXTYSrEZYL35nk8+NMaNfqSeEeoXqt3DsH4uXOcZgxCzZqbSJ2iSIuOBFUPYvIzBZ0qDMcGsE
fA/fAa1KMclHYWCubOkYQB9+VOywoyikiyOE4ZTLRCZ505TbP/o/ADa0GDgJSQwYuntHuHDO4Frt
lHs4qKWnLVXEblNHmMa69Hvhlm1WISNBzeZjM3RkZNcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
A7QcvaJaoCSHM9EJMg52CsZwo5zAPLUrKn6ZHj+AJXcwpd7Pfd+0vyFttjCRCD2rmUlTGU44OW34
AoPuQnH+ETWxj8AdPC9kGcZqpjEpXh+nfp27cp/67ZJIBdju5E+FkjFX7nQsjwFWVKTJ13G+4KXi
+8cDHrmLqjKKSf7aUHXoOmjsXQo7YTaykvM4Sp13g7wsZJFZsUKNGNi/fDG/+LNl7erctXGPKvat
guN1UEB86Sh/9BVY1SH4EWQshxcZpo/jRZzKFOup2DD6NQLYxFiMTvQy7tWJwaA+jUAa8ZzDgqow
W13+irxzqbkwqUoLzwhXYqhoPLlYL6jGH8i+uA==</ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
  <saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </saml2p:Status>
  <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id101630464297580882046872582" IssueInstant="2023-08-09T06:44:02.093Z" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/exk91vwiyk0PeANC25d7</saml2:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
        <ds:Reference URI="#id101630464297580882046872582">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
          <ds:DigestValue>QyNEk7ZgU3v5j57efbX1tUvT9vU2/VmNFYFLYnSVCRk=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>jevD05xiyy2U2ypjrxgQlaa6Rceut39giUHC5RIObxs0fxFa+IYEv+EW36rW5u+j/X5pJwbcuYMQVWEOzG5zLo4b5Q2scIyDu0nwymZLLZB8HwslZoAWv4hCas67tqdpKs+oE7aMWXSbRvcg2U22ryrKlJiRHTXJnTfxjIFffdZ6uYUC28MJCl0xE8iI9G1jNMDQU5MCi4gV0WsbXMzFlA4OZ1KhVwcKnwhopUm+RRDHpIIEB29S9ZQ9d/kwknp08KB2qIQqDSkcSBldoq3t28JHKP1cWHOP7b2OekhyZYDFRPRFMc1IIg+MIWrU8FKdnGNNdjYKc5xAqj9qsWQ9VQ==</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MIIDqDCCApCgAwIBAgIGAYdpe5zzMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA0MTAwNDQ0MjFaFw0zMzA0MTAwNDQ1MjFaMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEc
MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAKA4byPf3iEgVEL3NHfhZYCd6izBNa8lkmbT5ImHyjEJfqw0fTocmQRb5Nn3G3pg6MoX8yYG
v2wfcyXDt67Fio5vDsJ7BjxhmL13TuD/S2jUAX0qRgXrO40xlzkteoanWZSxbjQATKcp30VhkZS+
RYWuXTYSrEZYL35nk8+NMaNfqSeEeoXqt3DsH4uXOcZgxCzZqbSJ2iSIuOBFUPYvIzBZ0qDMcGsE
fA/fAa1KMclHYWCubOkYQB9+VOywoyikiyOE4ZTLRCZ505TbP/o/ADa0GDgJSQwYuntHuHDO4Frt
lHs4qKWnLVXEblNHmMa69Hvhlm1WISNBzeZjM3RkZNcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
A7QcvaJaoCSHM9EJMg52CsZwo5zAPLUrKn6ZHj+AJXcwpd7Pfd+0vyFttjCRCD2rmUlTGU44OW34
AoPuQnH+ETWxj8AdPC9kGcZqpjEpXh+nfp27cp/67ZJIBdju5E+FkjFX7nQsjwFWVKTJ13G+4KXi
+8cDHrmLqjKKSf7aUHXoOmjsXQo7YTaykvM4Sp13g7wsZJFZsUKNGNi/fDG/+LNl7erctXGPKvat
guN1UEB86Sh/9BVY1SH4EWQshxcZpo/jRZzKFOup2DD6NQLYxFiMTvQy7tWJwaA+jUAa8ZzDgqow
W13+irxzqbkwqUoLzwhXYqhoPLlYL6jGH8i+uA==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>
    <saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
      <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</saml2:NameID>
      <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml2:SubjectConfirmationData InResponseTo="_a5e37f1a-171f-4b89-b097-e4aa1a5c46af" NotOnOrAfter="2023-08-09T06:49:02.094Z" Recipient="http://directus.192.168.29.216.nip.io/auth/login/sso/acs"/>
      </saml2:SubjectConfirmation>
    </saml2:Subject>
    <saml2:Conditions xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" NotBefore="2023-08-09T06:39:02.094Z" NotOnOrAfter="2023-08-09T06:49:02.094Z">
      <saml2:AudienceRestriction>
        <saml2:Audience>directus.192.168.29.216.nip.io</saml2:Audience>
      </saml2:AudienceRestriction>
    </saml2:Conditions>
    <saml2:AuthnStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" AuthnInstant="2023-08-09T06:44:02.093Z" SessionIndex="_a5e37f1a-171f-4b89-b097-e4aa1a5c46af">
      <saml2:AuthnContext>
        <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
      </saml2:AuthnContext>
    </saml2:AuthnStatement>
  </saml2:Assertion>
</saml2p:Response>

To Reproduce

Setup

Following are the required docker-compose to setup the stack in local Change the IP 192.168.29.216 to you system's LAN IP which can be found using hostname -I on Linux or ipconfig getifaddr en0 on a Mac

Traefik

#docker-compose.yaml
version: "3.3"

services:

  traefik:
    image: "traefik:v2.9"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--experimental.plugins.traefik-themepark.modulename=github.com/packruler/traefik-themepark"
      - "--experimental.plugins.traefik-themepark.version=v1.3.0"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.entryPoints=web"
      - "traefik.http.routers.api.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
    ports:
      - "80:80"
      # - "8080:8080"
      - "443:443"
      
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - frontend
      - backend

  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.127.0.0.1.nip.io`)"
      - "traefik.http.routers.whoami.entrypoints=web"
    networks:
      - backend
      
networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

Directus

Replace SAML IDP Metadata with the one from your IDP setup:

version: '3'
services:
  mailhog:
    image: mailhog/mailhog
    container_name: 'mailhog'
    ports:
      - "1025:1025"
      - "8025:8025"
  database:
    container_name: database
    image: postgis/postgis:13-master
    # Required when running on platform other than amd64, like Apple M1/M2:
    # platform: linux/amd64
    volumes:
      - ./data/database:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: 'directus'
      POSTGRES_PASSWORD: 'directus'
      POSTGRES_DB: 'directus'

  directus:
    container_name: directus
    image: directus/directus:latest
    ports:
      - 8055:8055
    volumes:
      # By default, uploads are stored in /directus/uploads
      # Always make sure your volumes matches the storage root when using
      # local driver
      - ./uploads:/directus/uploads
      # Make sure to also mount the volume when using SQLite
      # - ./database:/directus/database
      # If you want to load extensions from the host
      # - ./extensions:/directus/extensions

      - database
    expose: 
    - 8055
    environment:
      KEY: '255d861b-5ea1-5996-9aa3-922530ec40b1'
      SECRET: '6116487b-cda1-52c2-b5b5-c8022c45e263'

      DB_CLIENT: 'pg'
      DB_HOST: 'database'
      DB_PORT: '5432'
      DB_DATABASE: 'directus'
      DB_USER: 'directus'
      DB_PASSWORD: 'directus'

      CACHE_ENABLED: 'false'

      ADMIN_EMAIL: '[email protected]'
      ADMIN_PASSWORD: 'd1r3ctu5'

      EMAIL_SMTP_NAME: local
      EMAIL_SMTP_HOST: mailhog
      EMAIL_SMTP_PORT: 1025
      EMAIL_FROM: [email protected]
      EMAIL_TRANSPORT: smtp
      AUTH_PROVIDERS: 'sso'
      AUTH_SSO_DRIVER: 'saml'
      AUTH_SSO_SP_metadata: ''
      AUTH_SSO_IDP_metadata: |
        <?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor entityID="http://www.okta.com/exk91vwiyk0PeANC25d7" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDqDCCApCgAwIBAgIGAYdpe5zzMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG
        A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
        MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEcMBoGCSqGSIb3DQEJ
        ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA0MTAwNDQ0MjFaFw0zMzA0MTAwNDQ1MjFaMIGUMQswCQYD
        VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
        A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0yMjIzMTgxMzEc
        MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
        ggEBAKA4byPf3iEgVEL3NHfhZYCd6izBNa8lkmbT5ImHyjEJfqw0fTocmQRb5Nn3G3pg6MoX8yYG
        v2wfcyXDt67Fio5vDsJ7BjxhmL13TuD/S2jUAX0qRgXrO40xlzkteoanWZSxbjQATKcp30VhkZS+
        RYWuXTYSrEZYL35nk8+NMaNfqSeEeoXqt3DsH4uXOcZgxCzZqbSJ2iSIuOBFUPYvIzBZ0qDMcGsE
        fA/fAa1KMclHYWCubOkYQB9+VOywoyikiyOE4ZTLRCZ505TbP/o/ADa0GDgJSQwYuntHuHDO4Frt
        lHs4qKWnLVXEblNHmMa69Hvhlm1WISNBzeZjM3RkZNcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
        A7QcvaJaoCSHM9EJMg52CsZwo5zAPLUrKn6ZHj+AJXcwpd7Pfd+0vyFttjCRCD2rmUlTGU44OW34
        AoPuQnH+ETWxj8AdPC9kGcZqpjEpXh+nfp27cp/67ZJIBdju5E+FkjFX7nQsjwFWVKTJ13G+4KXi
        +8cDHrmLqjKKSf7aUHXoOmjsXQo7YTaykvM4Sp13g7wsZJFZsUKNGNi/fDG/+LNl7erctXGPKvat
        guN1UEB86Sh/9BVY1SH4EWQshxcZpo/jRZzKFOup2DD6NQLYxFiMTvQy7tWJwaA+jUAa8ZzDgqow
        W13+irxzqbkwqUoLzwhXYqhoPLlYL6jGH8i+uA==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://dev-22231813.okta.com/app/dev-22231813_directus_1/exk91vwiyk0PeANC25d7/sso/saml"/><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://dev-22231813.okta.com/app/dev-22231813_directus_1/exk91vwiyk0PeANC25d7/sso/saml"/></md:IDPSSODescriptor></md:EntityDescriptor>
      PUBLIC_URL: "http://directus.192.168.29.216.nip.io"
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.directus.rule=Host(`directus.192.168.29.216.nip.io`)"
    - "traefik.http.routers.directus.entrypoints=web"
    - "traefik.http.routers.directus"
networks:
  default:
    external: true
    name: traefik_backend

Directus Version

v10.5.x

Hosting Strategy

Self-Hosted (Docker Image)

drpdishant avatar Aug 09 '23 07:08 drpdishant

The identifier is missing in the payload. Please meke sure that AUTH_<PROVIDER>_IDENTIFIER_KEY is set correctly, see https://docs.directus.io/self-hosted/config-options.html#saml and https://docs.directus.io/self-hosted/sso-examples.html.

paescuj avatar Aug 09 '23 07:08 paescuj

@paescuj please update the doc regarding the same.

image

As per this doc, it is assumed that if I am not providing AUTH_<PROVIDER>IDENTIFIER_KEY, it should default to the value of AUTH<PROVIDER>_EMAIL_KEY, for which default value is email. This implies that if both variables are not set by user the value shoud be email and that's what I am getting from my IDP. But I have to explicitly set both values.

drpdishant avatar Aug 09 '23 10:08 drpdishant

Although on Okta I also have to explicity add email key to attributes as it doesn't do it by default. I hope we can contribute to the doc to provide more working examples.

drpdishant avatar Aug 09 '23 10:08 drpdishant

I think you're right! The docs should be updated in this regard: https://github.com/directus/directus/blob/a885c7b86811d6877a2abb75bd1b668ff490c0cc/api/src/auth/drivers/saml.ts#L52-L53

paescuj avatar Aug 09 '23 10:08 paescuj

Seems like a copypasta issue from the OAuth docs. Might be nice to actually default to email to keep the functionality consistent with other SSO providers, rather than updating the docs.

aidenfoxx avatar Aug 09 '23 15:08 aidenfoxx