apokalipto / devise_saml_authenticatable

Devise SAML 2.0 authentication strategy
MIT License
294 stars 150 forks source link

SLO configuration (idp_slo_service_url vs single_logout_service_url) #243

Open morissetcl opened 9 months ago

morissetcl commented 9 months ago

Hey!

I am trying to use the SLO feature.

For context, I want to disconnect a user from my application who has been logged in via SAML from the Google Workspace UI. Basically, by disconnecting the user from the device tab or resetting the user's login cookies. This works well to disconnect the user from their Gmail, for example, but it's not reflected in the application where they were logged in using SAML.

Below my config

# devise.rb

  config.saml_configure do |settings|
    settings.assertion_consumer_service_url     = "#{Rails.application.secrets.saml_server_url}/users/saml/auth"
    settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    settings.name_identifier_format             = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    settings.issuer                             = "#{Rails.application.secrets.saml_server_url}/users/saml/metadata"
    settings.authn_context                      = ""
    settings.idp_slo_service_url                = "#{Rails.application.secrets.saml_server_url}/en/universal/logout"
    settings.idp_sso_target_url                 = Rails.application.secrets.saml_google_auth[:sso_url]
    settings.idp_cert_fingerprint               = Rails.application.secrets.saml_google_auth[:idp_cert_fingerprint]
    settings.idp_cert_fingerprint_algorithm     = "http://www.w3.org/2000/09/xmldsig#sha256"
  end

My questions:

I will expect to have information related to idp_slo_service_url but there is nothing. I went through the ruby-saml gem and I found out that they use the single_logout_service_url settings instead of idp_slo_service_url. When I do the change I have the following metadata

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_0e864883-081d-4aa5-930c-1a77daef99a3" entityID="https://admin.localhost:3000/users/saml/metadata">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://admin.localhost:3000/users/saml/idp_sign_out" ResponseLocation="https://my-website/users/saml/idp_sign_out"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://my-website/users/saml/auth" index="0" isDefault="true"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>

I have the SingleLogoutService info.

What do you think about that? Is single_logout_service_url should be used instead of idp_slo_service_url?

Thanks for your help.

adamstegman commented 9 months ago

idp_slo_service_url should be set to an SLO URL that Google gives you, not one local to your application—after signing out of your application, the SP, the user will be redirected there to complete the logout in the IdP. So I think it's not included in your metadata because it's not provided by your application.

I think single_logout_service_url may be used by Google—when a user signs out of Google, it can send a request to your application to let you know they should also be signed out of your application, the SP. Thus why it's in your metadata, in which case you shouldn't use idp_sign_out, you should probably use /users/sign_out.