Blog

Single Sign-On: Acronyms Demystified

Even if you understand the significance of adding SSO to your application, you may still feel overwhelmed by the different authentication-related acronyms and protocols. Nevertheless, after reading this post, we hope that you will have a better understanding of the distinctions between SAML, OIDC, and OAuth and feel more confident in implementing SSO in your application.


If you have gone through our Developer’s Guide to SSO, you should have some knowledge of what Single Sign-On is. In case you haven't read it yet, we highly recommend it as it serves as a great starting point. Essentially, SSO allows a user to utilize one set of login credentials to access multiple applications. This translates to a smoother experience, better security, and higher retention rates.

Even if you understand the significance of adding SSO to your application, you may still feel overwhelmed by the different authentication-related acronyms and protocols, which have numerous specifications that can take years to comprehend. Nevertheless, after reading this post, we hope that you will have a better understanding of the distinctions between SAML, OIDC, and OAuth and feel more confident in implementing SSO in your application.

OAuth 2.0 (Open Authorization)

OAuth is an open access delegation framework that uses HTTPS to authorize devices, APIs, servers, and applications with access tokens. Essentially, OAuth enables users to authorize one application to interact with another without requiring them to share their passwords.

OAuth has become nearly universal. Since the 2.0 specification was introduced over a decade ago, most modern internet users have been using OAuth without even realizing it.

To demonstrate, let's examine some options Spotify offers for authentication beyond basic email and password.

Spotify log in options

If you choose to use Facebook as your authentication, you'll see a prompt for access delegation that displays the following:

Spotify Facebook log in prompt

OAuth is a framework that allows users to grant applications access to resources without the need to share their passwords. In an OAuth flow, there are four primary actors involved:

  1. The Resource Owner: owns the data in the resource server
  2. The Resource Server: the API that stores the data we want to access
  3. The Client: the application that wants access
  4. The Authorization Server: OAuth’s main engine

As developers, it's important to understand the grant types available and choose the one that's most appropriate for the application.

One of the grant types that we'll explore in more detail here is the Authorization Code grant type. With this grant type, the user is redirected to the authorization server to grant access to the application. Once authorized, the authorization server sends an authorization code back to the application, which can then be exchanged for an access token.

OAuth flow

It's important to note that OAuth is not an authentication protocol. While OAuth can be used to build an authentication protocol and is the backbone of the OpenID Connect (OIDC) standard, it is primarily an authorization framework. The access token returned by OAuth lacks an authentication component and is scoped to the permissions that the user has granted (RFC 6749).

While OAuth is closely related to authentication, treating it as an authentication protocol can have security implications. OAuth should only be used for authorization purposes, and any authentication should be handled through a separate protocol. When a user grants authorization to an application, it doesn’t usually expire. Because of this, it can be hard to verify if a user is really there, which authentication protocols require.

Takeaways and Further Reading:

  • Because OAuth is an authorization framework it doesn’t verify the identity of a user (more about authentication vs authorization here)
  • On success, applications are granted access token from an authorization server allowing access through means other than basic authorization
  • Scopes provide a way to limit the amount of access granted in an access token (more about OAuth Scopes here)

OIDC (OpenID Connect)

OIDC is an authentication layer built on top of the OAuth 2.0 framework that returns the user’s identity as a JSON Web Token (JWT) called an ID Token. The primary actors in OIDC are:

  1. The End User: the entity for which we request identity information (this is equivalent to the RO in OAuth)
  2. Relying Party (RP): client that relies on the IDP in order to authenticate users and request claims
  3. OpenID Provider (OP): authorization server that offers authentication as a service.

These actors can engage in one of three supported flows:

  1. Authorization Code Flow: used by clients that can securely maintain a Client Secret between themselves and the Authorization Server. The Authorization Code Flow with Proof Key for Code Exchange (PKCE) is a popular choice, because of its ability to prevent authorization code injection.
  2. Implicit Flow: intended for clients that can not keep this secret. No longer recommended.
  3. Hybrid Flow: enables clients to obtain some tokens straight from the Authorization Endpoint, while still having the possibility to get others from the Token Endpoint.

Here is what an Authorization Code Flow with PKCE looks like:

PKCE introduces the concepts of code_verifier and code_challenge to the OIDC flow. The client creates and records a secret named called the “code_verifier”, and derives a transformed version “t(code_verifier)” (referred to as the “code_challenge”), which is sent in the OAuth 2.0 Authorization Request along with the transformation method “t_m”. This prevents Authorization Code Interception Attacks, particularly in mobile apps.

The ID Token we receive in step 5 will look a little something like this when it arrives:



:.eyJpc3MiOiJpc3N1ZXIiLCJzdWIiOiJpZHBfaWQiLCJleHAiOjE2Njc0MzA4MzMsImlhdCI6MTY2NzQzMDgzMywibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huZG9lQGNvbXBhbnkuY29tIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6IkRvZSJ9.Nf_yoQW9gasUHeTzsly4iEnYQIM795jw1Cw9WpNQM0s


The JWT is sent as a Base 64 encoded string, and can be decoded to reveal a JSON-formatted header, payload, and signature.

Here is an example of what the body containing a user’s claims might look like after decoding:



{
  "iss": "issuer",
  "sub": "idp_id",
  "exp": 1667430833,
  "iat": 1667430833,
  "name": "John Doe",
  "email": "johndoe@company.com",
  "given_name": "John",
  "family_name": "Doe"
}


Before creating a session for our user in our application we will need to verify:

  1. the signature used to sign the ID token
  2. the claims found in the ID token

The OIDC authentication process is simpler than the SAML verification process, which contributes to its popularity among developers. Upon successful validation of a user, their session can be created.

Takeaways and Further Reading:

SAML (Security Assertion Markup Language)

SAML is an authentication protocol widely employed by enterprises to enable federated authentication. In this scenario, a user has a single digital identity managed by an identity provider (IdP). The IdP establishes trust with other applications, allowing a user to sign in to multiple applications without separate passwords.

After the IdP establishes the user's identity, it returns an XML document called a SAML assertion containing the user's claims to the service provider (SP). The SP then uses this assertion to create a session for the user.

SAML is mostly utilized in enterprise environments, and it is probable that you have encountered it in the workplace. A well-known example is Okta:

In SAML there are three primary actors:

  1. User Agent: typically a web browser
  2. Service Provider (SP): the one issuing an authentication request, typically the application a user is logging into
  3. Identity Provider (IdP): the party providing authentication information for the user, in our example, Okta

These three actors come together to shape the SAML flow, which varies depending on whether the request is:

  1. IdP Initiated: a user logging in from the identity provider, such as by clicking the 1Password tile in Okta
  2. SP Initiated a user logging in from the application, such as by going to 1Password directly

Both are illustrated in the following flow:

Here is an example of a successful SAML response from Azure:



<samlp:Response ID="_f76e0426-0dfe-4ad5-8437-101c21bc01a7" Version="2.0" IssueInstant="2022-06-15T22:39:47.527Z" Destination="https://auth.workos.com/sso/saml/acs/VEbJPp4yuy6KCocOm84i8kUAg" InResponseTo="_01G5MRBMQ8661JM82DXSSRAWDF" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        https://sts.windows.net/e09b98e6-b42f-46f8-bad4-c67144108adb/
    </Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <Assertion ID="_93c6bf80-547c-4f08-a162-8f2ff0260500" IssueInstant="2022-06-15T22:39:47.511Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <Issuer>
            https://sts.windows.net/e09b98e6-b42f-46f8-bad4-c67144108adb/
        </Issuer>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <Reference URI="#_93c6bf80-547c-4f08-a162-8f2ff0260500">
                    <Transforms>
                        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    </Transforms>
                    <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                    <DigestValue>
                        yb6DO4I3jhH3Hk/OIjW/HaDvHY9/ibIRFM+pZDR6NTQ=
                    </DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>
                vXOHlIWrqyoysBrsKjVlqm3bV8+b54uHZZVHys8pZo5k8CjJW92+LjAI0L/O8zJRTjpLVTEhOXX6OajurzhxyjsTl2M3uVFp4T+gt2ONzbDRPmi2Kvr//BlJzNPHKrKxR5FcwJwBk8wYVb5ZEXrSHQ/ayTA5BWnGTiPNYfwLkkhJc2e0mt7Bd6fAg4ceMN7fnsIvydR5LrjdlqwpzKmAF2wwsjn02mhproSvRe82W+EfQKqT9OCahQTQtZlK/Ie7l0+X0bL/Xfdj7xsN9BacG1VCsDETka6MjqkFwkoXaK30oj4dWaj/kEszQI5dNH+9+8eu59LWLWG9lVzElcagxA==
            </SignatureValue>
            <KeyInfo>
                <X509Data>
                    <X509Certificate>
                        MIIC8DCCAdigAwIBAgIQWwqbxxTg2rhB7Zkuguu2cDANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQDEylNaWNyb3NvZnQgQXp1cmUgRmVkZXJhdGVkIFNTTyBDZXJ0aWZpY2F0ZTAeFw0yMjA2MTQyMzM4MDhaFw0yNTA2MTQyMzM4MDhaMDQxMjAwBgNVBAMTKU1pY3Jvc29mdCBBenVyZSBGZWRlcmF0ZWQgU1NPIENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzMXDqWCITTeSLEycCMMmlecWebmp6XVk5VUbgFoX1JH5g1oTccAH2fmFZrUwPM8ppKhYAXhPKoLd4WM3B7JT7dLcvwbshWG8KJ3Jk+U/Z4v5mXAm5gchOyw0PoSJ4hYq7noMiE1Wyjh/Xx2uOrnVF0551SAQulPZHiN3OqXoZbigADQ0GuG/dgc3nVeX7U5K28Vw6sZ9Ttdnt0361y5vdS1SdVMIw003adpjk6Yke2836aJ2cbEyv/94bnFxnj3uOEUWZ6Nu0ysCWdU07tgwDPAdWM/S0WF4ULNmjN3Gd+0/8cNlq9iVNroZlvhoFR6b+Ix992rQGEXOGF4/FjQMNQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA6w2NgwJYlYhFSQ3rtZFiLdDxeKE+JIHj0/U5tMxyShomK9PDQmSSf5XRoBEQFzf9Y9t/j/90MAA4Prqh7zceofFJnOux6RzAjJYEPDAS/Hfg4J1m67PBwITviaQUun+RFX8uinbjXSkjRpVAb89XOahTa4xIbb/iX/o/p1xh/+bo1L2IdFiCUB9BVNhoUkPwI5wm1qVyCqNQ71EckTBWtoc9EiMek4KcDKGA2DwE5ZnzWXgCJ4Hu6dJNoyMxZu92HzkuvUDE6J1uQiR4ld+BQjvz7zuBFeBA2gTseD9Ulm/CWrdHGY2+MPPeNg86L2O1VZqUqshdPNcoge2mzRc5I
                    </X509Certificate>
                </X509Data>
            </KeyInfo>
        </Signature>
        <Subject>
            <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
                email@foo-corp.com
            </NameID>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <SubjectConfirmationData InResponseTo="_01G5MRBMQ8661JM82DXSSRAWDF" NotOnOrAfter="2022-06-15T23:39:47.386Z" Recipient="https://auth.workos.com/sso/saml/acs/VEbJPp4yuy6KCocOm84i8kUAg"/>
            </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2022-06-15T22:34:47.386Z" NotOnOrAfter="2022-06-15T23:39:47.386Z">
            <AudienceRestriction>
                <Audience>
                    https://auth.gmail.com/VEbJPp4yuy6KCocOm84i8kUAg
                </Audience>
            </AudienceRestriction>
        </Conditions>
        <AttributeStatement>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
                <AttributeValue>
                    e09b98e6-b42f-46f8-bad4-c67144108adb
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
                <AttributeValue>
                    16344737-f3e0-4b2e-9654-291d1c9d2880
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
                <AttributeValue>
                    User Name
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
                <AttributeValue>
                    https://sts.windows.net/e09b98e6-b42f-46f8-bad4-c67144108adb/
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
                <AttributeValue>
                    http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password
                </AttributeValue>
                <AttributeValue>
                    http://schemas.microsoft.com/claims/multipleauthn
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
                <AttributeValue>
                    First
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
                <AttributeValue>
                    Last
                </AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                <AttributeValue>
                    email@foo-corp.com
                </AttributeValue>
            </Attribute>
        </AttributeStatement>
        <AuthnStatement AuthnInstant="2022-06-14T23:31:54.403Z" SessionIndex="_93c6bf80-547c-4f08-a162-8f2ff0260500">
            <AuthnContext>
                <AuthnContextClassRef>
                    urn:oasis:names:tc:SAML:2.0:ac:classes:Password
                </AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
    </Assertion>
</samlp:Response>


The XML format may pose challenges for quick human parsing, but even a cursory glance reveals the assertion that contains user attributes such as name, first name, last name, and email. These attributes can be utilized by the service provider (SP) to create sessions for the user.

However, the receipt of an assertion with claims alone does not suffice to create a session. The validity of the assertion must also be verified by the application per the SAML specification, by validating the response signature. However, even with this validation, the application remains vulnerable to security threats. In the event that an assertion is deemed invalid at any point in the process, a session should not be created for the user.

Once the validity of an assertion is confirmed, the attributes in the response can be employed to create a session.

Takeaways and Further Reading:

  • SAML authentication can be either IdP or SP initiated (more in the WorkOS documentation here)
  • A successful response will return a user’s identity in the form of an XML document called the SAML assertion
  • SAML is well established and feature rich, so it’s a popular choice with businesses.
  • It is relatively easy to accidentally introduce security vulnerabilities in SAML implementations.

Conclusion

After reading this post, you should have a greater understanding of the technical differences between SAML, OIDC, and OAuth. However, if the prospect of managing these diverse flows, protocols, and identity providers still seems overwhelming, there are third-party vendors available who specialize in offering a secure, efficient, and user-friendly approach to implementing SSO.  WorkOS simplifies many of the complexities discussed in this post and seamlessly delivers a standardized profile object to your application upon successful authentication.



const profile = {
  id: 'prof_01DMC79VCBZ0NY2099737PSVF1',
  connection_id: 'conn_01E4ZCR3C56J083X43JQXF3JK5',
  organization_id: 'org_01EHWNCE74X7JSDV0X3SZ3KJNY',
  connection_type: 'OktaSAML',
  email: 'todd@foo-corp.com',
  first_name: 'Todd',
  idp_id: '00u1a0ufowBJlzPlk357',
  last_name: 'Rundgren',
  object: 'profile',
  raw_attributes: {},
};


The decision to build or buy can be challenging for any organization. However, if you find the idea of implementing a centralized SSO API to streamline authentication appealing, WorkOS's Single Sign-On product may be the perfect fit for your needs. To explore how WorkOS can simplify your authentication process and experience the benefits firsthand, don't hesitate to get in touch with our team today.

In this article

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.