This repo contains a minimal example app built with Next.js and NextAuth that supports SAML using the SSOReady NextAuth provider.
SSOReady is an open-source way to add SAML and SCIM support to your application.
To check out this repo yourself, you'll need a working installation of Node. Then, run:
git clone https://github.com/ssoready-example-app-nextjs-nextauth-saml
cd ssoready-example-app-nextjs-nextauth-saml
npm install
npm run dev
Then, visit http://localhost:3000.
SSOReady can act as a NextAuth provider, a lot like how you'd add support for "Log in with Google" or "Log in with GitHub".
The result is that there's two steps involved in implementing SAML:
- Adding SSOReady as a NextAuth provider
- Calling NextAuth's
signIn
with thessoready-saml
provider.
The rest is handled by SSOReady and NextAuth for you.
In this demo app, NextAuth is configured at
pages/api/auth/[...nextauth].js
:
import NextAuth from "next-auth";
export const authOptions = {
providers: [
{
id: "ssoready-saml",
name: "SSOReady SAML",
type: "oauth",
wellKnown:
"https://auth.ssoready.com/v1/oauth/.well-known/openid-configuration",
profile(profile) {
return {
id: profile.sub,
email: profile.sub,
organizationId: profile.organizationId,
organizationExternalId: profile.organizationExternalId,
};
},
clientId: process.env.SSOREADY_CLIENT_ID,
clientSecret: process.env.SSOREADY_CLIENT_SECRET,
},
],
};
export default NextAuth(authOptions);
SSOREADY_CLIENT_ID
and SSOREADY_CLIENT_SECRET
are configured in
.dev.local
.
The demo app logs a user in with SAML by calling NextAuth's signIn
with the
ssoready-saml
provider and an organizationExternalId
:
// This state also controls the email <input> next to the "Log in with SAML" button.
const [email, setEmail] = useState("john.doe@example.com");
// The handler for the "Log in with SAML" button.
const onLogInWithSAML = () => {
signIn("ssoready-saml", undefined, {
// convert "john.doe@example.com" into "example.com"
organizationExternalId: email.split("@")[1],
});
};
Every customer's SAML servers live on a different URL, so you need to know which
customer is trying to log in with SAML in order to sign in. That's what
organizationExternalId
does.
To make this demo app work out of the box, we did some work for you. You'll need to follow these steps yourself when you integrate SAML into your app.
The steps we took were:
-
We signed up for SSOReady at https://app.ssoready.com.
-
We created an environment, and configured its redirect URL to be
http://localhost:3000/ssoready-callback
. -
We created a SAML OAuth Client. Because this is a demo app, we hard-coded it into
.dev.local
. In production, make sure to keepSSOREADY_CLIENT_SECRET
a secret. -
We created two organizations, both of which use DummyIDP.com as their "corporate" identity provider:
- One organization has external
ID
example.com
and a domain whitelist of justexample.com
. - The second organization has extnernal ID
example.org
and domain whitelistexample.org
.
- One organization has external
ID
In production, you'll create a separate organization for each company that wants SAML. Your customers won't be using DummyIDP.com; that's just a SAML testing service that SSOReady offers for free. Your customers will instead be using vendors including Okta, Microsoft Entra, and Google Workspace. From your code's perspective, those vendors will all look exactly the same.
This demo app gives you a crash-course demo of how to implement SAML end-to-end. If you want to see how this all fits together in greater detail, with every step described in greater detail, check out the SAML NextAuth.js integration docs or the rest of the SSOReady docs.