hslavich / OneloginSamlBundle

OneLogin SAML Bundle for Symfony
MIT License
149 stars 94 forks source link

You must activate the logout in your security firewall configuration. #194

Closed damionbroadaway closed 2 years ago

damionbroadaway commented 2 years ago

Hello there.

Thank you for the bundle. It's been very helpful. However, I've hit a snag right at the end. I can't logout.

Can't seem to find much in the documentation other than to put a few lines in the config. Which I believe I've done.

Context:

Application is mostly an API. We are adding a few user-facing pages. Isolated to /dashboard/* and /audit/*. All other routes have their own auth for the API functionality.

Currently, everything works. Catches the auth requirement, forwards to Google, back to use, and all the right paths are secure.

But trying to logout at /saml/logout gives the error found below. Additionally, you will find the current contents of the bundle config and the security config. It is accurate except for what you see as REDACTED.

Any help is appreciated.

Symfony: 5.4.6 OneloginSamlBundle: 2.8.0 SSO Provider: Google

Error Message:

{
   "status":"error",
   "detail":{
      "errors":[
         "You must activate the logout in your security firewall configuration."
      ],
      "errorId":"627D30CD15A1C8.88904140",
      "trace":"#0 \/var\/www\/REDACTED\/vendor\/symfony\/http-kernel\/HttpKernel.php(152): Hslavich\\OneloginSamlBundle\\Controller\\SamlController-\u003EsingleLogoutServiceAction()\n#1 \/var\/www\/REDACTED\/vendor\/symfony\/http-kernel\/HttpKernel.php(74): Symfony\\Component\\HttpKernel\\HttpKernel-\u003EhandleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)\n#2 \/var\/www\/REDACTED\/vendor\/symfony\/http-kernel\/Kernel.php(202): Symfony\\Component\\HttpKernel\\HttpKernel-\u003Ehandle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#3 \/var\/www\/REDACTED\/public\/index.php(20): Symfony\\Component\\HttpKernel\\Kernel-\u003Ehandle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#4 {main}"
   }
}

security.yaml:

security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        saml_provider:
            entity:
                class: 'App\Entity\Doctrine\User'
                property: 'email'
        # used to reload user from session & other features (e.g. switch_user)
        api_user_provider:
            id: api_user_provider
    firewalls:
        # order is important here
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api:
            pattern: ^/(api|task)/
            anonymous: false
            lazy: false
            logout: ~
            stateless: true
            provider: api_user_provider
            user_checker: App\Security\ApiUserChecker
            guard:
                authenticators:
                    - App\Security\ApiKeyAuthenticator
        app:
            pattern: ^/(dashboard|saml/acs|audit)
            provider: saml_provider
            saml:
                username_attribute: email
                use_attribute_friendly_name: false
                check_path: saml_acs
                login_path: saml_login
            logout:
                path: saml_logout

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/dashboard/, roles: ROLE_USER }
        - { path: ^/saml/acs/, roles: ROLE_USER }
        - { path: ^/audit/, roles: ROLE_ADMIN }
        - { path: ^/api/, roles: ROLE_API }
        - { path: ^/task/, roles: ROLE_TASK }
        - { path: ^/audit/, roles: ROLE_AUDITOR }

    role_hierarchy:
        ROLE_ADMIN: [ ROLE_USER ]
        ROLE_SUPER_ADMIN: [ ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH, ROLE_AUDITOR ]

hslavich_onelogin_saml.yanl:

hslavich_onelogin_saml:
  # Basic settings
  idp:
    entityId: 'https://accounts.google.com/o/saml2?idpid=REDACTED'
    singleSignOnService:
      url: 'https://accounts.google.com/o/saml2/idp?idpid=REDACTED'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    singleLogoutService:
      url: 'https://accounts.google.com/o/saml2/idp?idpid=REDACTED'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    x509cert: '%env(SSO_509_CERT)%'
  sp:
    # https://my-domain.com/saml/metadata
    entityId: '%app.sso.meta%'
    assertionConsumerService:
      # https://my-domain.com/saml/acs
      url: '%app.sso.acs%'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
    singleLogoutService:
      # https://my-domain.com/saml/logout
      url: '%app.sso.logout%'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    privateKey: ''
  # Optional settings
  # https://my-domain.com/saml/saml
  baseurl: '%app.sso.base_url%'
  strict: true
  debug: true
  security:
    wantNameId: true
    nameIdEncrypted: false
    authnRequestsSigned: false
    logoutRequestSigned: false
    logoutResponseSigned: false
    wantMessagesSigned: false
    wantAssertionsSigned: false
    wantNameIdEncrypted: false
    requestedAuthnContext: true
    signMetadata: false
    wantXMLValidation: true
    relaxDestinationValidation: false
    destinationStrictlyMatches: true
    rejectUnsolicitedResponsesWithInResponseTo: false
    signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
    digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256'
  contactPerson:
    technical:
      givenName: 'REDACTED'
      emailAddress: 'REDACTED'
    support:
      givenName: 'REDACTED'
      emailAddress: 'REDACTED'
    administrative:
      givenName: 'REDACTED'
      emailAddress: 'REDACTED'
  organization:
    en:
      name: 'REDACTED'
      displayname: 'REDACTED'
      url: 'REDACTED'
a-menshchikov commented 2 years ago

Hi @damionbroadaway! As I see, your security.firewalls.app.pattern doesn't handle (match) /saml/logout URI.

damionbroadaway commented 2 years ago

I see. That is a bit confusing from the documentation. I was unaware that the logout path had to be included.

I will give it a try.

damionbroadaway commented 2 years ago

That almost worked. It directed me to Google. But they are telling me it's a malformed_request.

Could that still be the result of my configuration?

On the page:

null. That’s an error. Error parsing the request, malformed_request: The SAML request is malformed. That’s all we know.

Here is the SAML Logout Request:

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                     ID="ONELOGIN_bc4ceeb965f18f4583e7a688cb7958725c4b301e"
                     Version="2.0"
                     IssueInstant="2022-05-12T21:33:02Z"
                     Destination="https://accounts.google.com/o/saml2/idp?idpid=REDACTED"
                     >
    <saml:Issuer>https://my-domain-is-removed/saml/metadata</saml:Issuer>
    <saml:NameID>my.user@email.com</saml:NameID>
    <samlp:SessionIndex>_68b802b527f1ab367d72b91b03b66749</samlp:SessionIndex>
</samlp:LogoutRequest>
damionbroadaway commented 2 years ago

Google Workspace does not support SLO because it will log them out of all Google services.

Looks like I can use Symfony's default logout just to remove the session.

Closing. Thank you for the help.