Introduction
Single Sign-On (SSO) is a method of authentication that allows a user to access multiple applications with one set of login credentials. SAML (Security Assertion Markup Language) is a popular protocol used for implementing SSO. Integrating SAML-based SSO into Drupal enables users to authenticate once and access various Drupal-powered applications seamlessly.
SAML
Security Assertion Markup Language (SAML) is an XML-based open standard for exchanging authentication and authorization data between parties, in particular, between an identity provider (IdP) and a service provider (SP). In the context of Drupal, the Drupal instance acts as the service provider, and an external identity provider handles authentication.
Types of SSO Protocols
Single Sign-On (SSO) can be implemented using various protocols. Some of the commonly used protocols include:
- Lightweight Directory Access Protocol (LDAP)
- Kerberos
- Security Assertion Markup Language (SAML)
- OAuth 2
- OpenID Connect
- XML
- Certificate and Key Generation
XML
XML (eXtensible Markup Language) is a markup language akin to HTML. It enables the storage and transportation of data.
Example:
<start>
<first>Data1</first>
<new>NewData</new>
</start>
Creating Certificates and Keys
Certificates and private keys play a vital role in SAML-based SSO. They ensure security by authenticating incoming requests.
To generate an OpenSSL certificate and private key, run this command in your terminal:
openssl req -x509 -nodes -sha256 -days 3650 -newkey rsa:2048 -keyout private_key.key -out certificate.crt
Operational Mechanism
In SAML SSO, we designate the application requesting login as a Service Provider (SP), while the application providing authentication data is the Identity Provider (IdP).
Workflow:
- Upon a user's login attempt to the SP, the browser dispatches a request to the SP server.
- The SP generates a SAML request (encapsulating SAML data in XML format) and redirects it to the configured IdP URL (in SP) for authentication.
- Subsequently, the IdP verifies the SAML data from the request XML against the pre-configured data of the SP (in IdP).
- Upon successful validation, the IdP formulates an XML-formatted SAML response to the ACS URL from the SP's SAML request, containing the current email address (by default, but it can be overridden) along with other data for validation.
- At this point, the SP verifies the data in the SAML response and authorizes the user associated with the email address provided in the SAML response.
Both the SAML request and SAML response are encrypted and decrypted within the redirected application (SP/IdP).
Drupal is commonly utilized as a service provider, although it can also be expanded to function as an identity provider.
Three distinct types of SAML Request (AuthNRequest) can be employed:
- AuthNRequest
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24" Version="2.0" ProviderName="SP test" IssueInstant="2014-07-16T23:52:45Z" Destination="http://idp.example.com/SSOService.php" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs">
<saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
</samlp:AuthnRequest>
- With Signature (HTTP-Redirect binding)
bM441nuRIzAjKeMM8RhegMFjZ4L4xPBHhAfHYqgnYDQnSxC++Qn5IocWuzuBGz7JQmT9C57nxjxgbFIatiqUCQN17aYrLn/mWE09C5mJMYlcV68ibEkbR/JKUQ+2u/N+mSD4/C/QvFvuB6BcJaXaz0h7NwGhHROUte6MoGJKMPE=
- AuthNRequest with embedded signature (HTTP-POST binding)
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx41d8ef22-e612-8c50-9960-1b16f15741b3" Version="2.0" ProviderName="SP test" IssueInstant="2014-07-16T23:52:45Z" Destination="http://idp.example.com/SSOService.php" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs">
<saml:Issuer>http://sp.example.com/demo1/metadata.php</saml: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/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#pfx41d8ef22-e612-8c50-9960-1b16f15741b3">
<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/2000/09/xmldsig#sha1"/>
<ds:DigestValue>yJN6cXUwQxTmMEsPesBP2NkqYFI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>g5eM9yPnKsmmE/Kh2qS7nfK8HoF6yHrAdNQxh70kh8pRI4KaNbYNOL9sF8F57Yd+jO6iNga8nnbwhbATKGXIZOJJSugXGAMRyZsj/rqngwTJk5KmujbqouR1SLFsbo7Iuwze933EgefBbAE4JRI7V2aD9YgmB3socPqAi2Qf97E=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQQFADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcwMDI5MjdaFw0xNTA3MTcwMDI5MjdaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vU/6R/OBA6BKsZH4L2bIQ2cqBO7/aMfPjUPJPSn59d/f0aRqSC58YYrPuQODydUABiCknOn9yV0fEYm4bNvfjroTEd8bDlqo5oAXAUAI8XHPppJNz7pxbhZW0u35q45PJzGM9nCv9bglDQYJLby1ZUdHsSiDIpMbGgf/ZrxqawIDAQABo1AwTjAdBgNVHQ4EFgQU3s2NEpYx7wH6bq7xJFKa46jBDf4wHwYDVR0jBBgwFoAU3s2NEpYx7wH6bq7xJFKa46jBDf4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQCPsNO2FG+zmk5miXEswAs30E14rBJpe/64FBpM1rPzOleexvMgZlr0/smF3P5TWb7H8Fy5kEiByxMjaQmml/nQx6qgVVzdhaTANpIE1ywEzVJlhdvw4hmRuEKYqTaFMLez0sRL79LUeDxPWw7Mj9FkpRYT+kAGiFomHop1nErV6Q==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
Reference: https://www.samltool.com/generic_sso_req.php
Various types of SAML Response include:
- SAML Response
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
<saml:Subject>
<saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
<saml:AudienceRestriction>
<saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">test@example.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
<saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
Additional types are available at https://www.samltool.com/generic_sso_res.php.
Both the request and response can be sent using either GET or POST methods.
Integrating Single Sign-On (SSO) into Drupal via SAML
Drupal offers various modules for implementing SSO as both a Service Provider (SP) and Identity Provider (IdP). Below are some of the modules available for each:
SP Modules:
IdP Modules:
Testing Tools:
Although SAML data is encrypted, debugging SAML requests can be facilitated with the following tools:
- SAML Tracer for Mozilla Firefox.
- SAML Chrome Panel for Google Chrome.
Configuration Steps for SSO Module in SP
To configure Drupal as a Service Provider using the saml_sp module, follow these steps:
- Create a certificate and private key, placing them in a Drupal-readable location.
- Install the module using Composer:
composer require 'drupal/saml_sp:^4.2' - Enable the module in the Extend section of Drupal.
- Access the module configuration page (/admin/config/people/saml_sp).
- Configure SP settings:
- Specify the entityID if overriding the default https://sp.lndo.site/user.
- Provide an assertion URL similar to https://sp.lndo.site/saml/consume.
- Enter other mandatory details.
- If using Sign, specify the correct algorithm and select the Assertion and Encryption type based on the IdP's requirements.
- Provide the paths to the certificate and private key files. Metadata will be generated based on this data, which is then used to configure SP data in the IdP.
Configuring Identity Providers in SP
1. Under Identity Providers, click on Add Service Provider.
2. Enter the data from the metadata file
or URL provided by the IdP.
In SAML SP, the Drupal Login module can be utilized once the configurations are complete. Configure the SAML login process under the Login Menu. For example, if a user without an account in SP but with an account in IdP logs in, an account is automatically created in SP with an authenticated role.
Setting up SSO Module in IdP
For establishing Drupal as an Identity Provider (IdP), we've utilized the light_saml_idp module.
Configuration of IdP Module:
- Create and store the certificate and private key in a location accessible by Drupal.
- Install the module.
- Activate the module in the Extend section of Drupal.
Access the configuration at /admin/config/people/light_saml_idp:
- Provide the entity_id.
- Fill in other necessary details.
- Ensure accurate file paths for the certificate and private_key.
- Metadata will be generated under the Metadata tab once data is provided. This metadata is crucial for SP configuration.
- Add the Service Provider under the Service Provider section, using data from the SP metadata.
With successful configuration, SSO functionality should work seamlessly. Congratulations, SSO integration is complete!
If issues arise with SSO, utilize testing tools to diagnose and resolve any problems.
Implementation
To integrate SSO into Drupal via SAML, you typically need to:
- Configure Drupal as a service provider.
- Set up an external identity provider (IdP) that supports SAML.
- Exchange metadata between Drupal and the IdP.
- Configure user attributes and mappings.
- Test the SSO setup thoroughly.
Best Practices
- Choose a reliable SAML-based SSO solution that integrates well with Drupal.
- Follow security best practices to ensure the integrity and confidentiality of authentication data.
- Regularly update and maintain the SSO integration to address security vulnerabilities and compatibility issues.
Conclusion
Integrating Single Sign-On (SSO) into Drupal via SAML enhances user experience, simplifies authentication management, and improves overall security. By following best practices and leveraging robust SAML solutions, Drupal websites can provide seamless access to authenticated users across multiple applications.