# 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](https://docs.propelauth.com/sso/enterprise-sso/getting-started).

## [OAuth Integration](https://docs.propelauth.com/sso/enterprise-sso/other-providers#o-auth-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 an 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**.

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

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:

```javascript
   Bearer {ACCESS_TOKEN}
   ```

5. **Jwks endpoint**: `GET {YOUR_ISSUER_URL}/.well-known/jwks.json`

## [Mapping Attributes](https://docs.propelauth.com/sso/enterprise-sso/other-providers#mapping-attributes)

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

```javascript
{
  "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.

- 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:

```html
{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:

```jsx
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:

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.

The value of the `state` parameter should be a randomly generated string, stored locally, and match the returned state once the user is redirected back to you. [More info here](https://developers.google.com/identity/openid-connect/openid-connect#createxsrftoken).

```
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}'
```

The body of the request is x-www-form-urlencoded and not json

This will return a json object:

```javascript
{
    "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.

```javascript
{
  "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 manage your users with Enterprise SSO!
