This guide walks you through integrating Azure Single Sign-On (SSO) into your React web application built with Next.js 14 and App Router.
Prerequisites:
- React 18
- Next.js 14
- App Router (using
app
folder structure)
Understanding App Router and NextAuth Configuration:
App Router can be slightly trickier for handling redirections during SSO implementation. We’ll leverage next-auth
to simplify the process.
Step 1: Installation
Begin by installing the next-auth
package using npm:
npm install next-auth
Step 2: Configuring NextAuth for App Router
Since you’re using App Router, navigate to the app
folder within your project’s src
directory. Here’s how to set up the configuration:
- Create an
api
folder insideapp
. - Within
api
, create anauth
folder. - Inside
auth
, create a folder named[...nextauth]
. - Finally, create a file named
router.ts
inside[...nextauth]
.
The complete path should resemble
src/app/api/auth/[...nextauth]/router.ts
Step 3: Setting Up NextAuth Configuration (router.ts):
Here’s the router.ts
code with explanations for each section:
import NextAuth from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";
const { AZURE_AD_CLIENT_ID, AZURE_AD_CLIENT_SECRET, AZURE_AD_TENANT_ID } =
process.env;
if (!AZURE_AD_CLIENT_ID || !AZURE_AD_CLIENT_SECRET || !AZURE_AD_TENANT_ID) {
throw new Error("The Azure AD environment variables are not set.");
}
const handler = NextAuth({
// Secret used to sign and encrypt tokens (replace with a strong secret)
secret: AZURE_AD_CLIENT_SECRET,
providers: [
AzureADProvider({
clientId: AZURE_AD_CLIENT_ID,
clientSecret: AZURE_AD_CLIENT_SECRET,
tenantId: AZURE_AD_TENANT_ID,
}),
],
// Callbacks for modifying JWT and Session objects
callbacks: {
async jwt({ token, account }) {
if (account) {
// Add access token to the JWT token
token = Object.assign({}, token, {
access_token: account.access_token,
});
}
return token;
},
async session({ session, token }) {
if (session) {
// Add access token to the session object
session = Object.assign({}, session, {
access_token: token.access_token,
});
console.log(session); // Optional: Log session data for debugging
}
return session;
},
},
});
export { handler as GET, handler as POST };
Note: You can decode access_token and id_token to fetch groups, token_expiry etc with help of jwt-decode subject to your requirements.
- Environment Variables: Replace placeholders like
AZURE_AD_CLIENT_ID
with your actual Azure AD application credentials. - Secret: Set a strong secret value for signing and encrypting tokens.
- Azure AD Provider: This configures Azure AD as the authentication provider for your application.
- JWT and Session Callbacks: These functions allow you to customize the data stored in the JWT (JSON Web Token) and session objects. In this case, we’re adding the access token received from Azure AD to both.
Step 4: Wrapping Your App with SessionProvider (layout.tsx):
Next, we need to wrap your application with SessionProvider
from next-auth/react
in your layout.tsx
file:
import React from "react";
import { SessionProvider } from "next-auth/react";
// ... other imports
export default function RootLayout({ children }) {
// ... other component logic
return (
<html lang="en">
<body>
<SessionProvider>
{/* Your application components go here */}
{children}
</SessionProvider>
</body>
</html>
);
}
This ensures the session information is accessible throughout
Step 5: Setting up login and logout methods.
// login.tsx
import { signIn } from "next-auth/react";
const handleLoginClick = async () => {
try {
signIn();
} catch (error) {
console.error(error);
}
};
<Button
variant="contained"
color="primary"
fullWidth
onClick={handleLoginClick}
>
Login
</Button>;
// logout.tsx
import { signOut } from "next-auth/react";
const handleLogOutClick = async () => {
try {
signOut();
} catch (error) {
console.error(error);
}
};
<Button
variant="contained"
color="primary"
fullWidth
onClick={handleLogOutClick}
>
Login
</Button>;
This is the basic set up required to enable SSO
with Azure AD
. Additional configurations can be configured. guide here
Please comment your questions/clarifications.
Leave a comment