apps/docs/content/guides/integrate/login/saml.mdx
SAML stands for Security Assertion Markup Language. It is a standard commonly used for identity federation and single sign-on (SSO). It is one of the original and most popular standards for SSO. Although it is prone to certain security flaws and exploits if not implemented correctly, it remains relevant and widely used.
Here are some reasons why organizations might choose SAML:
Legacy systems compatibility
SAML has been in use since 2002 and is deeply integrated into many legacy systems and enterprise environments. Organizations with existing SAML infrastructure may prefer to continue using it to avoid costly and complex migrations.
Enterprise use cases
SAML is often favored in enterprise settings where detailed user attributes and complex authorization requirements are necessary. Its support for rich metadata and customizable assertions makes it suitable for intricate access control scenarios.
Mature ecosystem
The SAML ecosystem is mature, with extensive support from a wide range of enterprise applications and identity providers. This broad compatibility ensures that SAML can be used seamlessly across various platforms and services.
The Service Provider (SP) is the application that the user is trying to sign into. When the service provider sends a communication to the identity provider, it is called a SAML request. When the Identity Provider (IdP) responds or sends a communication to the service provider, it is called a SAML response.
Within the SAML response, there are multiple statements about the user, known as assertions. These assertions are all signed using XML signatures (also known as DSig) and are sent to be processed at the service provider's specific endpoint called an Assertion Consumer Service (ACS). The ACS is responsible for receiving the SAML response from the identity provider, checking the assertions' signatures, and validating the entire document. This is a crucial part of implementing SAML from the service provider's perspective.
Additionally, the SAML response contains other pieces of information about the user, such as their first name, last name, and other profile information, referred to as attributes.
Another important concept in SAML is the relay state. The relay state allows the identity provider to remember where a user was before authentication. If a user is browsing anonymously through the service provider and triggers authentication, they will be redirected to the identity provider. After validating the user's identity, the identity provider will redirect them back to the service provider's ACS. The relay state makes sure that the user returns to their original location instead of being dropped on a generic home page.
SAML trust is the configuration between the identity provider and the service provider, involving shared information such as a signing certificate and an entity ID (also known as an issuer) from the identity provider. This shared information establishes a trust that allows both parties to validate communications, requests, and responses.
Metadata is another crucial term in SAML. Metadata allows for self-configuration between the identity provider and the service provider. Instead of manually exchanging certificates, endpoint URLs, and issuer information, metadata enables the sharing of an XML configuration file or URLs to these files. This allows the service provider and identity provider to self-configure based on the information within these configuration files, making the process less manual and more convenient.
One important aspect of SAML is that the user can initiate the authentication process in two primary workflows:
1. IdP-Initiated: The user starts at the IdP, which sends a SAML response to the SP.
Commonly, with workforce identity providers, there is a centralized user portal where a user can see a list of applications. Clicking on one of these applications initiates the authentication process without the user first going to the service provider. This method is called IdP-initiated (Identity Provider-initiated) authentication. In this flow, the user goes to the identity provider, which automatically kicks off the SAML response, directing them to the desired application.
2. SP-Initiated: The user starts at the SP, which sends a SAML request to the IdP, followed by a SAML response from the IdP.
The other method is SP-initiated (Service Provider-initiated) authentication. Here, the user starts at the service provider, which then sends a SAML request to the identity provider. The identity provider processes this request and sends back a SAML response. In IdP-initiated flows, there is no SAML request, while in SP-initiated flows, the SAML request and response are both involved. The identity provider must understand how to receive a SAML request and create a SAML response. The service provider, particularly its Assertion Consumer Service (ACS), needs to validate the SAML response and potentially generate a SAML request if SP-initiated flow is supported.
It's important to note that not all service providers support both methods. Some only support IdP-initiated, while others only support SP-initiated. The choice between supporting IdP-initiated or SP-initiated authentication depends on the specific requirements of the product and the preferences of the developer implementing SAML. ZITADEL, for instance, supports only the SP-initiated flow.
SAML uses XML for both requests and responses. A typical SAML request from an SP to an IdP includes an ID, timestamp, destination URL, and issuer information. The IdP processes this request and returns a SAML response containing user assertions, which the SP validates.
Let's delve into what a SAML request and response look like with the following shortened examples.
Sample SAML request
<?xml version="1.0" encoding="utf-8"?>
<ns0:AuthnRequest
xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol" ID="id-8LjuzBEUQFYFWjL55" Version="2.0" IssueInstant="2024-06-11T04:13:52Z" Destination="https://my-instance-xtzfbc.zitadel.cloud/saml/v2/SSO" AssertionConsumerServiceURL="http://127.0.0.1:5000/acs">
<ns1:Issuer
xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://zitadel-test.sp/metadata
</ns1:Issuer>
<ns2:Signature
xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<ns2:SignedInfo>
<ns2:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ns2:CanonicalizationMethod>
<ns2:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ns2:SignatureMethod>
<ns2:Reference URI="#id-8LjuzBEUQFYFWjL55">
<ns2:Transforms>
<ns2:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ns2:Transform>
<ns2:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ns2:Transform>
</ns2:Transforms>
<ns2:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ns2:DigestMethod>
<ns2:DigestValue>WSz/EQ72RZ0DTh3DBSRCElpITqM=</ns2:DigestValue>
</ns2:Reference>
</ns2:SignedInfo>
<ns2:SignatureValue>HHjsNh0OLj7...</ns2:SignatureValue>
<ns2:KeyInfo>
<ns2:X509Data>
<ns2:X509Certificate>MIIDtzCCAp+gAwIBAgIUfITRQGue...</ns2:X509Certificate>
</ns2:X509Data>
</ns2:KeyInfo>
</ns2:Signature>
</ns0:AuthnRequest>
In this SAML request:
These XMLs are stringified, encoded, and transmitted according to the SAML binding used. For instance, in HTTP Redirect Binding, the request is sent as URL parameters, while in HTTP POST Binding, it is included in the request body. The signature's transmission method also depends on the binding used, ensuring the integrity and authenticity of the SAML message across different communication channels.
Sample SAML response
<?xml version="1.0" encoding="utf-8"?>
<Response
xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ID="_164ba12b-6711-40e0-8ddb-55aa810f1c92" InResponseTo="id-8LjuzBEUQFYFWjL55" Version="2.0" IssueInstant="2024-06-11T04:17:41Z" Destination="http://127.0.0.1:5000/acs">
<Issuer
xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://my-instance-xtzfbc.zitadel.cloud/saml/v2/metadata
</Issuer>
<Status>
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></StatusCode>
</Status>
<Assertion
xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_6fbdb616-b77f-46af-9554-989c8b89eeda" IssueInstant="2024-06-11T04:17:41Z">
<Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://my-instance-xtzfbc.zitadel.cloud/saml/v2/metadata</Issuer>
<Signature
xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
<Reference URI="#_6fbdb616-b77f-46af-9554-989c8b89eeda">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
<DigestValue>/b1R9LJJSeNX...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>n5GbV4xhkXV...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIFITCCAwmgAwIBAgIBUTANBgkqh...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData NotOnOrAfter="2024-06-11T04:22:41Z" Recipient="http://127.0.0.1:5000/acs" InResponseTo="id-8LjuzBEUQFYFWjL55"></SubjectConfirmationData>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2024-06-11T04:17:41Z" NotOnOrAfter="2024-06-11T04:22:41Z">
<AudienceRestriction>
<Audience>https://zitadel-test.sp/metadata</Audience>
</AudienceRestriction>
</Conditions>
<AuthnStatement AuthnInstant="2024-06-11T04:17:41Z" SessionIndex="_6fbdb616-b77f-46af-9554-989c8b89eeda">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
<AttributeStatement>
<Attribute Name="Email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>[email protected]</AttributeValue>
</Attribute>
<Attribute Name="SurName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>Stark</AttributeValue>
</Attribute>
<Attribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>Tony</AttributeValue>
</Attribute>
<Attribute Name="FullName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>Tony Stark</AttributeValue>
</Attribute>
<Attribute Name="UserName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>[email protected]</AttributeValue>
</Attribute>
<Attribute Name="UserID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<AttributeValue>260242264868201995</AttributeValue>
</Attribute>
</AttributeStatement>
</Assertion>
</Response>
In this SAML response:
See Let Users Login with Preferred Identity Provider for more information.
Implementing SAML securely involves several best practices:
SAML has its flaws; it can be complex and cumbersome to implement. The primary alternatives to consider is OpenID Connect (OIDC). Some illustrate this with the following analogy: “SAML is to OpenID Connect as SOAP is to REST." Just as REST was created to address some inherent flaws in SOAP, OpenID Connect was created to address some of the limitations in specifications like SAML. OpenID Connect is flexible, easy to use, widely adopted, and reliably secure.
For example, SAML is not well-suited for desktop and mobile applications due to its reliance on HTTP redirects, cookie-based session management, and complex certificate handling. OIDC, on the other hand, offers a modern, flexible, and simpler solution for authentication and authorization needs across desktop and mobile applications. It uses authorization codes and tokens that are easier to manage and supports custom URL schemes and deep linking, which simplifies the handling of redirects and improves the overall user experience. Furthermore, OIDC offers more flexibility in managing sessions without relying solely on cookies.
If a project requires SAML due to specific requirements or existing infrastructure, it should be used. However, for new projects, it is advisable to consider OpenID Connect because it is a more modern standard and is the more popular choice in the industry.
To test SAML scenarios with ZITADEL, follow these steps:
Integrate a SAML SP with ZITADEL as the IdP:
Integrate ZITADEL with another SAML IdP for identity brokering:
Create test users and simulate authentication requests:
Simulate various scenarios:
For more information, refer to SAML Endpoints in ZITADEL.