Integrating with Other Providers

If you already have an auth provider but now need to support SAML or Enterprise-level Single Sign-On (SSO), this guide is for you! If you haven't already, make sure to check out our guide on getting your project ready for Enterprise SSO.

OAuth Integration

Now that we have everything prepared on the PropelAuth side, let's now create an OAuth integration that we'll use to log users in with SAML. This part could be drastically different depending on your auth provider, so we'll try to provide as much information as possible so you can track down everything you need. Check out your auth provider's documentation for connecting to a OpenID Connect (OIDC) Provider for more information.

Start by heading over to the Frontend Integration page, clicking on Advanced Settings followed by Edit OAuth Config.

accessing oauth settings

Here, we can generate a Client ID and Client Secret.

OAuth Settings

While we're here, let's also add a Redirect URI. This is the URL that PropelAuth will redirect to after the user logs in. This could be the URL to your app, but more likely a URL provided by your auth provider.

You might need to provide some URLs to your auth provider so it knows where to retrieve authorization, an access token, and more.

  1. Issuer URL: {YOUR_AUTH_URL} (found in the Backend Integration page in your PropelAuth dashboard)
  2. Authorization endpoint: GET {YOUR_ISSUER_URL}/propelauth/oauth/authorize
  3. Token endpoint: POST {YOUR_ISSUER_URL}/propelauth/oauth/token
  4. UserInfo endpoint: GET {YOUR_ISSUER_URL}/propelauth/oauth/userinfo
    • Expects an access token to be passed in via an Authorization header like so:
    Bearer {ACCESS_TOKEN}
    
  5. Jwks endpoint: GET {YOUR_ISSUER_URL}/.well-known/jwks.json

Mapping Attributes

PropelAuth provides your auth provider with a JSON object which includes user details, orgs, and roles via the UserInfo endpoint.

{
  "can_create_orgs": false,
  "created_at": 1711127287,
  "email": "test@propelauth.com",
  "email_confirmed": true,
  "enabled": true,
  "first_name": "Anthony",
  "has_password": true,
  "last_active_at": 1712328977,
  "last_name": "Edwards",
  "locked": false,
  "metadata": null,
  "mfa_enabled": false,
  "org_member_info": {
    "org_id": "35905720-f22a-4f36-b082-7f35bb32463f",
    "org_metadata": {},
    "org_name": "PropelAuth",
    "url_safe_org_name": "propelauth",
    "inherited_user_roles_plus_current_role": [
        "Owner",
        "Admin",
        "Member"
    ],
    "user_permissions": [
        "propelauth::can_invite",
        "propelauth::can_change_roles",
        "propelauth::can_remove_users",
        "propelauth::can_setup_saml",
        "propelauth::can_manage_api_keys"
    ],
    "user_role": "Owner"
  },
  "picture_url": "https://img.propelauth.com/2a27d237-db8c-4f82-84fb-5824dfaedc87.png",
  "properties": {
    "favoriteSport": "Basketball"
  },
  "sub": "0497bbe6-49c1-4bc7-9e9c-c75846722c73",
  "update_password_required": false,
  "user_id": "0497bbe6-49c1-4bc7-9e9c-c75846722c73"
}

Creating a Sign in With Enterprise SSO Login

Now that we have a provider set up, let’s create a sign-in button in our login page.

Enterprise SSO is not as simple as a “Sign in with Google” (or Social SSO) option. You can’t just place a button that says “Sign in with Okta” because you need to know which Okta account they are signing in to.

Some common examples include:

  • Ask for the user’s email address up front, see if an SSO connection exists for it, and if so, begin the login process. Otherwise, ask for their password.

The user belongs to an org result

  • Adding a “Sign in with SSO” button - when the user presses it, we prompt them for their email address.
  • Adding a “Sign in with SSO” button - when the user presses it, we prompt them for their organization’s name.

PropelAuth provides options that support all of these and more, but let’s look at the second example where we collect the user’s email address. We can check if an email address has a SAML connection by fetching the following endpoint:

{YOUR_AUTH_URL}/api/fe/v3/login/check?email={YOUR_USERS_EMAIL}

If the user has a SAML connection, the request will return a SAML login URL. If not, it will return a 404. Let’s create a button that checks if the user has a SAML connection:


function SignUpPage() {
  const [email, setEmail] = useState('')
  const [message, setMessage] = useState(null);
  
  const loginWithEnterpriseSSO = async () => {
    let response = await fetch(`{YOUR_AUTH_URL}/api/fe/v3/login/check?email=${email}`);
    if (response.status === 200) {
      handleProviderLogin()
    } else if (response.status === 404) {
      setMessage("User does not belong to an org")
    }
  };
  
  const handleProviderLogin = async () => {
    // TODO: kick off an OAuth flow, this will vary based on your setup. 
    // Feel free to reach out to us at support@propelauth.com if you need any help
    setMessage("The user belongs to an org")
  }
 
  return (
    <div>
      <input
        type="email"
        placeholder="Enter your email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <button onClick={loginWithEnterpriseSSO}>
        Login With Enterprise SSO
      </button>
      {message && <div>{message}</div>}
    </div>
  );
}
  
export default SignUpPage

When we test this out with a user who belongs to an org with a SAML connection, we should see this as a result:

The user belongs to an org result

If you're handling the OAuth flow yourself, start it by directing the user to PropelAuth's /propelauth/oauth/authorize endpoint. We'll need to include a redirect_uri and client_id values from the OAuth Config page in PropelAuth.

If you include an org_name, org_id, domain, or email parameter your user will automatically be redirected to their IdP.

curl --location '{YOUR_AUTH_URL}/propelauth/oauth/authorize?
state={STATE}
&redirect_uri={YOUR_REDIRECT_URI}
&client_id={YOUR_CLIENT_ID}
&response_type=code
&domain={YOUR_USERS_DOMAIN}'

This will return a code as a query parameter which we'll use for our next request, a POST request to the /propelauth/oauth/token endpoint to retrieve an access token.

The Authorization header uses basic auth with client_id as the username and client_secret as the password.

curl --location '{YOUR_AUTH_URL}/propelauth/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic {base64 encoded {YOUR_CLIENT_ID} : {YOUR_CLIENT_SECRET}}' \
--data-urlencode 'redirect_uri={YOUR_REDIRECT_URI}' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code={CODE_FROM_PREVIOUS_STEP}'

This will return a json object:

{
    "access_token": "eyJ0eXA...",
    "token_type": "bearer",
    "expires_in": 1800,
    "refresh_token": "0e04d63...",
    "id_token": "eyJ0eXAi..."
}

We can now use the access_token as a bearer token to retrieve the user's details via a fetch to the /propelauth/oauth/userinfo endpoint.

curl --location '{YOUR_AUTH_URL}/propelauth/oauth/userinfo' \
--header 'Authorization: Bearer eyJ0eXAi...' \

This will return the user's information as well as organization and role.

{
  "sub": "813a8a12-eecc-4629-a36e-16e73d094b54",
  "user_id": "813a8a12-eecc-4629-a36e-16e73d094b54",
  "email": "test@propelauth.com",
  "email_confirmed": true,
  "has_password": false,
  "first_name": "Anthony",
  "last_name": "Edwards",
  "picture_url": "https://img.propelauth.com/2a27d237-db8c-4f82-84fb-5824dfaedc87.png",
  "properties": {
      "favoriteSport": "Basketball",
      "tos": true
  },
  "metadata": null,
  "locked": false,
  "enabled": true,
  "mfa_enabled": false,
  "can_create_orgs": false,
  "created_at": 1712783690,
  "last_active_at": 1712785416,
  "org_member_info": {
    "org_id": "4896c602-7c67-4d32-a25d-5adb9a15a60e",
    "org_name": "PropelAuth",
    "org_metadata": {},
    "url_safe_org_name": "propelauth",
    "user_role": "Member",
    "inherited_user_roles_plus_current_role": [
        "Member"
    ],
    "user_permissions": []
  },
  "update_password_required": false
}

And that’s it! Your users can now:

  • Setup SAML
  • Login via SAML
  • Show up with org details, roles, and user properties when they login

You’re now all set and ready to managing your users with Enterprise SSO!