On this page
SAML
Traditionally, enterprise apps are deployed and run within the company network. For apps to obtain user information, many enterprise apps are built to integrate with corporate directories like Microsoft Active Directory. More importantly, a user's credentials are typically stored and validated using the directory. For example, if you use SharePoint and Exchange that are running on-premises, your sign-in credentials are your Active Directory credentials.
However, with increased collaboration and the move towards cloud-based environments, many apps have moved beyond the boundaries of a company's domain. Federated authentication is the solution to this problem.
Authentication
Authentication defines the way that a user is identified and validated through credentials as part of a sign-in flow. Most apps present a sign-in page to a user, allowing the user to specify a username and a password. Sometimes, additional information may be required to locate the user, like a company ID or a client code. This information allows the app to narrow the search of the username that's applicable to the provided info. This is often used to allow the same username to exist across multiple tenants that belong to different organizations.
Most apps have a user store (database or LDAP) that contains, among other things, user profile information and credentials. When a user signs in, the credentials are validated against this user store. The advantage of this approach is that everything is managed within the app, providing a single and consistent way to authenticate a user.
However, if a user needs to access multiple apps where each one requires a different set of credentials, the process is more complicated. First, the user needs to remember different passwords in addition to any other corporate password (for example, their AD password). The user is now forced to maintain separate usernames and passwords, and must handle different password policies and expirations. This scenario also creates headaches for admins and independent software vendors (ISV) when users continue to have access to apps that should have been revoked.
Federated identity
Federated identity supports app access beyond a company or organization boundary. Imagine a relationship between a juice company (JuiceCo) selling its product to a large supermarket chain (BigMart). As an employee of JuiceCo, you need to access an app provided by BigMart to manage the relationship and monitor supplies and sales.
In this case, BigMart (who is providing this app) needs to manage user authentication. The simple way is to require a different username and password from users working at JuiceCo. But with many users to maintain, this can be complicated - especially with all the suppliers and their users who need to access the app.
A better way to solve this problem is to allow JuiceCo, and every other supplier, to share or "federate" the identities with BigMart. As a JuiceCo employee, you already have a corporate identity and credentials. Federated identity provides a secure way for the supermarket chain (Service Provider) to externalize authentication. They do this by integrating with the existing identity infrastructure of its suppliers (Identity Provider).
This type of use case is what led to the birth of federated protocols like Security Assertion Markup Language (SAML). See the Mozilla Infosec article on SAML (opens new window).
Plan for SAML
SAML is mostly used as a web-based authentication mechanism because it relies on using the browser agent to broker the authentication flow. At a high-level, the authentication flow of SAML looks like this:
The following common SAML terms are important to understand during the planning stage:
Service Provider (SP): The entity providing the service, typically in the form of an app
Identity Provider (IdP): The entity providing the identities, including the ability to authenticate a user. The IdP typically also contains the user profile, which contains additional information about the user. Depending on the app, some SPs may require a simple profile (username, email). Other SPs may require a richer set of user data (job code, department, address, location, manager).
SAML Request: Also known as an authentication request. Generated by the SP to "request" an authentication.
SAML Response: Generated by the IdP. It contains the actual assertion of the authenticated user. A SAML response may also contain additional information, such as user profile or group/role information, depending on what the SP can support.
Service Provider Initiated (SP-initiated) sign-in: Describes the SAML sign-in flow when initiated by the SP. This is typically triggered when the end user tries to access a resource or sign in directly on the SP side.
Identity Provider Initiated (IdP-initiated) sign-in: Describes the SAML sign-in flow initiated by the IdP. Instead of a redirect from the SP triggering the SAML flow, the IdP initiates a SAML response. This SAML response is redirected to the SP to assert the user's identity.
A couple of key things to note:
The SP never directly interacts with the IdP. A browser acts as the agent to carry out all the redirects.
The SP needs to know which IdP to redirect to before it has any idea who the user is.
The SP doesn't know who the user is until the SAML assertion comes back from the IdP.
This flow doesn't have to start from the SP. An IdP can initiate an authentication flow.
The SAML authentication flow is asynchronous. The SP doesn't know if the IdP ever completes the entire flow. Because of this, the SP doesn't maintain any state of authentication requests generated. When the SP receives a response from an IdP, the response must contain all the necessary information.
Plan checklist
While the SAML protocol is a standard, there are different ways to implement it depending on the nature of your app. The following is a checklist of some key considerations.
Understanding the role of an SP
Single and multiple IdPs
Understanding the SP-initiated sign-in flow
Exposing SAML configuration in the SP
Enabling SAML for everyone vs a subset of users
Implementing a "backdoor"
Understand the role of an SP
A SAML IdP generates a SAML response based on a configuration that's mutually agreed to by the IdP and the SP. After receiving the SAML assertion, the SP must validate that the assertion comes from a valid IdP. Then, the SP must parse the necessary information from the assertion, such as attributes.
To do this, the SP requires at least the following:
- Certificate: The SP needs to obtain the public certificate from the IdP to validate the signature. The certificate is stored on the SP side and used whenever a SAML response arrives.
- ACS Endpoint - Assertion Consumer Service URL: Often referred to simply as the SP sign-in URL. This is the endpoint provided by the SP where SAML responses are posted. The SP needs to provide this information to the IdP.
- IdP Sign-in URL: The endpoint on the IdP side where SAML requests are posted. The SP needs to obtain this information from the IdP.
The easiest way to implement SAML is to use an open-source SAML toolkit. There's a list of recommended toolkits in several languages at the end of this page. These toolkits provide the logic needed to digest the information in an incoming SAML response. Also, if the SP needs to support the SP-initiated sign-in flow, the toolkits provide the logic to generate an appropriate SAML authentication request.
Single IdP vs multiple IdPs
When you’re building an internal integration, you might want to SAML-enable it to integrate with your corporate SAML IdP. In this situation, you would have to support only a single IdP. Your integration only needs to deal with a single set of IdP metadata (cert, endpoints, and so on).
ISVs who are building an enterprise SaaS product or an external-facing website/portal/community for customers and partners should consider supporting multiple IdPs. This is the typical use case for many SaaS ISVs that need to integrate with customers' corporate identity infrastructure. Depending on your app's architecture, think about ways to store the SAML configuration from each IdP. Also, consider how to provide the necessary SP information for each.
A key consideration involves the ACS URL endpoint on the SP side where SAML responses are posted. It’s possible to expose only one endpoint even when dealing with multiple IdPs. For a single-instance multi-tenant app where the tenancy isn't defined in the URL, this is a simpler implementation. However, you must rely on additional information in the SAML response (such as the IssuerID) to determine which IdP is trying to authenticate. Apps set up in a multi-tenant fashion with domain information in the URL (for example, using either https://domain1.example.com
or https://www.example.com/domain1
) can benefit from having an ACS URL endpoint for each subdomain. It's a good option since the URL itself identifies the domain.
Understand SP-initiated sign-in flow
As discussed earlier, an IdP-initiated sign-in flow starts from the IdP. So, there’s no additional context about what the user is trying to access on the SP side. The only context is that the user is trying to get authenticated and access the SP. Typically, after the user is authenticated, the browser is redirected to a generic landing page in the SP.
In an SP-initiated flow, the user tries to access a protected resource directly on the SP side without the IdP being aware of the attempt. Two issues arise:
The need to identify the right IdP if authentication of a federated identity is required. With sign-in flows that are SP-initiated, the SP initially doesn't know anything about the identity. Determine how the SP can determine which IdP should receive the SAML request. Sometimes the IdP can be identified when users click an app URL with subdomain information that's mapped to a unique tenant and IdP. If this isn't the case, then prompt the user for additional information. You need something that allows the SP to identify which IdP the user belongs to. Remember, you’re only prompting for an identifier, not credentials. Okta supports passing the identifier to the IdP with the LoginHint parameter. Then, the user doesn't need to input the identifier again when redirected to the IdP to sign in. For instructions on how to trigger Okta to send the LoginHint to the IdP, see Redirect with SAML deep links.
Support for deep links. Most apps support deep links. For example, you might receive a link to a document that resides on a content management system. Ideally, if you need to authenticate before accessing the document, you would like to be taken to the document immediately after authentication.
SAML is an asynchronous protocol by design. The SP-initiated sign-in flow begins by generating a SAML authentication request that gets redirected to the IdP. At this point, the SP doesn't store any information about the request. When the SAML response comes back from the IdP, the SP wouldn't know anything about the initial deep link that triggered the authentication request. Luckily, SAML supports this with a parameter called relayState
.
A relayState
is an HTTP parameter that you can include as part of the SAML request and response. In an SP-initiated sign-in flow, the SP can set the relayState
parameter in the SAML request with additional information about the request. After receiving the SAML request, the SAML IdP attaches the relayState
value as an HTTP parameter in the SAML response after the user authenticates. This way, when the round trip completes, the SP can use the relayState
information to get more context about the initial SAML authentication request.
In the case of a deep link, the SP sets the relayState
of the SAML request with the deep link value. When the SAML response is returned, the SP can use the relayState
value and take the authenticated user to the right resource.
For instructions to construct a deep link for SAML IdPs, see Redirect with SAML deep links.
Expose SAML configuration in the SP
As discussed earlier, the SP needs the IdP configuration to complete the SAML setup. While many ISVs choose to do this through support and email, there’s a better way. Expose a self-service administrator page for your customer's IT admin to enable SAML. SAML supports metadata on both the IdP and SP side. One way to configure the IdP/SP relationship on the SP side is to build the ability to receive an IdP metadata file. Then, build the ability to generate an SP metadata file for consumption by the IdP. This is the preferred method.
However, some ISVs choose to allow configuration of several key SAML parameters directly rather than through a metadata file. Typical parameters would include the IdP redirect URL (for SAML request), IssuerID, and IdP Logout URL. The SP must also allow the IdP public certificate to be uploaded or saved.
Using a metadata file is preferred because it can handle any future additions/enhancements to your SAML support without making UI changes. UI changes would be required if you exposed specific SAML configuration parameters in your UI.
Enable SAML for everyone or a subset of users
Depending on the nature of your app, there might be reasons to allow only a subset of users to be SAML enabled. Imagine an app that internal employees and external users access. The employees may use SAML to sign in to the app, while the external users may use a separate set of credentials.
A smaller subset of users is useful even in proof-of-concept cases where the intent is to have all users of a tenant be SAML-enabled. It's also useful during testing and rollout.
Implement a backdoor
This is important when you want to SAML-enable all users in your app. Sometimes, there might be a mistake in the SAML configuration - or something changes in SAML IdP endpoints. You don't want the system to lock you out. Having a backdoor available for an admin to use to access a locked system is important. This is often accomplished by having a "secret" sign-in URL that doesn't trigger a SAML redirection when accessed. Typically, the admin uses a username and password to sign in and make the necessary changes to fix the problem.
Reference
SAML 2.0
- Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0 (opens new window)
- Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0 (opens new window)
- Profiles for the OASIS Security Assertion Markup Language (SAML) V2.0 (opens new window)