# Integrating Enterprise SSO with NextAuth

If you’re already using NextAuth for authentication, 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).

## [NextAuth Setup](https://docs.propelauth.com/sso/enterprise-sso/nextauth#next-auth-setup)

Now that we have everything prepared on the PropelAuth side, let's create a provider in our NextAuth app that we'll use to log users in with SAML. 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**. We'll be using these in the next step.

While we're here, let's also add a **Redirect URI**. The URI should be your Application's URL + `/api/auth/callback/PropelAuthProvider`. For example:

```
http://localhost:3000/api/auth/callback/PropelAuthProvider
```

Moving over to your NextAuth project, create a `.env.local` file in your root directory and add the following, replacing the values with your own. You can find `YOUR_AUTH_URL` in the **Frontend Integrations** page in your PropelAuth dashboard:

```
PROPELAUTH_PROVIDER_CLIENT_ID={YOUR_CLIENT_ID}
PROPELAUTH_PROVIDER_CLIENT_SECRET={YOUR_CLIENT_SECRET}
PROPELAUTH_AUTH_URL={YOUR_AUTH_URL}
```

Next, create a new file in your project called `PropelAuthProvider.js` where we'll build a custom OAuth provider.

```jsx
export default function PropelAuthProvider() {
  return {
    id: 'PropelAuthProvider',
    name: 'PropelAuthProvider',
    idToken: true,
    type: 'oauth',
    version: '2.0',
    issuer: process.env.PROPELAUTH_AUTH_URL,
    jwks_endpoint: `${process.env.PROPELAUTH_AUTH_URL}/.well-known/jwks.json`,
    authorization: `${process.env.PROPELAUTH_AUTH_URL}/propelauth/oauth/authorize`,
    clientId: process.env.PROPELAUTH_PROVIDER_CLIENT_ID,
    clientSecret: process.env.PROPELAUTH_PROVIDER_CLIENT_SECRET,
    token: `${process.env.PROPELAUTH_AUTH_URL}/propelauth/oauth/token`,
    userinfo: `${process.env.PROPELAUTH_AUTH_URL}/propelauth/oauth/userinfo`,
    profile(data) {
      return {
        id: data.user_id,
        email: data.email,
      }
    }
  }
}
```

If you haven't already done so, create a file called `[...nextauth].js` in your `pages/api/auth` directory. Here we will add the `PropelAuthProvider` we created in the last step as a provider, as well as add some callbacks to handle user information. This is where you can customize the user data that will be available to you via the [useSession() hook](https://next-auth.js.org/getting-started/client#usesession), such as `org_id` and `role`.

```jsx
import NextAuth from "next-auth";
// Update the location of the PropelAuthProvider
import PropelAuthProvider from "../../providers/PropelAuthProvider";

export default NextAuth({
  providers: [
    PropelAuthProvider(),
  ],
  callbacks: {
    async jwt(token) {
      if (token.profile) {
        token.token.org_id = token.profile.org_member_info.org_id
        token.token.org_name = token.profile.org_member_info.org_name
        token.token.role = token.profile.org_member_info.user_role
      }
      return token.token;
    },
    async session(session) {
      return session
    }
  }
});
```

### Creating a Sign in Page

Now that we have everything set up in PropelAuth as well as a provider in NextAuth, let’s add a "Login With Enterprise SSO" button to our sign in 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 () => {
    const response = await fetch(`{YOUR_AUTH_URL}/api/fe/v3/login/check?email=${email}`);
    if (response.status === 200) {
      setMessage("The user belongs to an org")
    } else if (response.status === 404) {
      setMessage("User does not belong 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:

Let’s now update the `loginWithEnterpriseSSO` function to handle the NextAuth login and call it when our SAML check succeeds. **[Here’s some additional documentation](https://next-auth.js.org/getting-started/client#signin)** on the `signIn` function that we’ll be using. Instead of using the `email` property, you can also use `domain`, `org_id`, or `org_name`.

```jsx
const loginWithEnterpriseSSO = async () => {
  const response = await fetch(`{YOUR_AUTH_URL}/api/fe/v3/login/check?email=${email}`);
  if (response.status === 200) {
    signIn("PropelAuthProvider", null, { email: email })
  } else if (response.status === 404) {
    setMessage("User does not belong to an org")
  }
};
```

We can now update the page to check if a user is signed in. For this example, we'll be using the `useSession` hook.

```jsx
"use client"
import { useSession } from "next-auth/react";
import React, { useState } from 'react';

function SignUpPage() {
  const session = useSession();

if (session.status === 'loading') {
    return "Loading or not authenticated..."
  } else if (session.status === "unauthenticated") {
    return (
      // SSO Enterprise Login Button
    );
  } else {
    return (
      <div>
        {session && <h2>Welcome, {session.data.token.email}</h2>}
      </div>
    );
  }
}

export default SignUpPage
```

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!
