SAML SSO in Okta is less about granting access to "any app" and more about an app securely delegating its authentication responsibility to Okta.
Let’s say you have a cloud service, like a CRM or a project management tool, and you want your users to be able to log into it using their existing Okta credentials. Instead of that app having to manage its own username/password database, handle password resets, and worry about brute-force attacks, it can say, "Okta, you handle all that. When a user tries to log into my app, just ask Okta if they’re who they say they are. If Okta says yes, let them in. If Okta says no, keep them out." This is SAML SSO in a nutshell.
Here’s a simplified view of what happens when a user tries to access a SAML-enabled application through Okta:
- User Clicks App Link: The user navigates to the SaaS application’s login page or clicks a link from their Okta dashboard.
- App Redirects to Okta: The SaaS app, configured as a SAML Service Provider (SP), doesn’t handle the login directly. Instead, it sends a SAML
AuthnRequestto Okta (the SAML Identity Provider, IdP). This request essentially says, "Please authenticate this user and tell me who they are." - Okta Authenticates User: Okta checks if the user is already logged into Okta.
- If they are, Okta proceeds to step 4.
- If they’re not, Okta presents its own login page (username/password, MFA, etc.). Once successfully authenticated by Okta, it proceeds to step 4.
- Okta Generates SAML Assertion: Okta creates a SAML
Assertion, which is an XML document. This assertion contains information about the authenticated user, like their username, email, and potentially other attributes (e.g., department, role). It’s digitally signed by Okta to prove its authenticity and integrity. - Okta Sends Assertion Back to User’s Browser: Okta sends this SAML assertion back to the user’s web browser.
- Browser Submits Assertion to App: The user’s browser then automatically posts this SAML assertion (via an HTTP POST binding) to a specific Assertion Consumer Service (ACS) URL on the SaaS application.
- App Verifies Assertion and Logs User In: The SaaS application receives the SAML assertion. It verifies Okta’s digital signature to ensure the assertion hasn’t been tampered with and that it actually came from Okta. If valid, the app extracts the user’s identity from the assertion and logs them into the application, granting them access.
The core configuration involves setting up trust between Okta (the IdP) and the application (the SP). This trust is established using metadata.
Okta Configuration (IdP Side):
- Application Name: A friendly name for the application.
- SAML Signing Certificate: Okta uses its private key to sign SAML assertions. You’ll need to download Okta’s public certificate to give to the application.
- Identity Provider Single Sign-On URL: The URL on Okta where the application will send
AuthnRequests. - Identity Provider Issuer: A unique identifier for Okta as the IdP.
- Attribute Statements: This is where you define what user attributes (like
email,firstName,lastName,username,department) Okta should send to the application in the SAML assertion. You map these to Okta user profile attributes. - Single Logout (SLO): If configured, this allows a user to log out of one application and have that logout propagate to other SAML-connected apps, and also to Okta itself.
Application Configuration (SP Side):
- Assertion Consumer Service (ACS) URL: The specific URL on the application where Okta’s browser will post the SAML assertion.
- Audience URI (SP Entity ID): A unique identifier for the application itself. This is what Okta will expect in the
AuthnRequestand will include in the assertion to ensure it’s being sent to the correct destination. - Single Logout URL (Optional): For SLO.
- Identity Provider Certificate: The public certificate from Okta (the IdP) that the application uses to verify the signature on incoming SAML assertions.
- Identity Provider Single Sign-On URL: The URL on Okta where the application should send
AuthnRequests. - Identity Provider Issuer: Okta’s entity ID.
The "magic" is in the metadata exchange. Okta provides a metadata URL or downloadable XML file that contains all its IdP information. Similarly, the application provides its metadata. You paste these into each other’s configurations.
When you configure an app in Okta for SAML SSO, you’ll typically go to "Applications" > "Applications" > "Create App Integration". You select "SAML 2.0" as the sign-in method. Then, you’ll be prompted to enter details about the application.
For many common SaaS apps, Okta has pre-built templates. You just search for the app (e.g., "Salesforce," "Slack," "Google Workspace"), and Okta pre-populates many of the necessary SAML settings. You still need to provide the application-specific details like the ACS URL and Audience URI, which you get from the application’s admin console.
The most surprising thing about SAML SSO is that the user’s browser is the crucial intermediary; the SAML assertion travels from Okta to the browser, and then from the browser to the application, rather than directly from Okta to the application.
Let’s look at a real-world example of a SAML assertion fragment. When Okta asserts an identity, it’s sending XML that looks something like this (simplified and with placeholders):
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_some-unique-id" Version="2.0" IssueInstant="2023-10-27T10:00:00Z">
<saml:Issuer>https://your-company.okta.com/app/abcdefg1234567890/sso/saml</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<!-- Digital signature details here -->
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">user@example.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2023-10-27T10:05:00Z" Recipient="https://app.example.com/acs"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2023-10-27T09:59:00Z" NotOnOrAfter="2023-10-27T10:05:00Z">
<saml:AudienceRestriction>
<saml:Audience>https://app.example.com/sp-entity-id</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2023-10-27T09:59:30Z" SessionIndex="_another-unique-id">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="firstName">
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">John</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="lastName">
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Doe</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="email">
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">user@example.com</saml:AttributeValue>
</saml:Attribute>
<!-- ... other attributes ... -->
</saml:AttributeStatement>
</saml:Assertion>
The <saml:Issuer> is Okta’s identifier. The <saml:Audience> within <saml:AudienceRestriction> is the application’s entity ID, ensuring the assertion is meant for this app. The <saml:NameID> is the primary identifier for the user (often email). The <saml:AttributeStatement> is where custom attributes are passed. The NotOnOrAfter times are critical for preventing replay attacks.
The next step is understanding how to handle different SAML binding types (HTTP-Redirect, HTTP-POST, HTTP-Artifact) and how to troubleshoot assertion validation failures.