5.6 Securing a Next.js Application
Securing Next.js with ZTrust via NextAuth.js OAuth
ZTrust integrates with Next.js applications using NextAuth.js, an authentication library for Next.js. By configuring ZTrust as an OAuth 2.0 / OpenID Connect (OIDC) provider, your Next.js app delegates authentication to ZTrust while handling sessions, tokens, and user identity securely. This setup enables single sign-on (SSO), secure API access, and session management, with a clean and reliable implementation.
Prerequisites
Before integrating your Next.js application with ZTrust, ensure the following are in place:
ZTrust SSO – A running ZTrust instance configured as your identity and access management provider.
Next.js Application – A Next.js project already set up. Authentication will be handled using NextAuth.js.
Configured Realm and Client – A realm and client created in ZTrust with OIDC enabled. The client settings (Client ID, Secret, Redirect URIs) will be required by your Next.js app.
With these prerequisites, your application will be ready to establish a secure connection with ZTrust using OpenID Connect.
Step 1: Set up ZTrust
Access ZTrust Admin Console:
Fig 5.6.a: Master realm welcome page Click on Manage Realms in the sidebar to view the list of realms available in your ZTrust.
Fig 5.6.b: List of avalible realms under manage realms From the list of realms, select the realm where you want to secure Next application.
Fig 5.6.c: Welcome to Demo realm From the left sidebar, navigate to the Clients section.
Fig 5.6.d: Navigating to clients section in side bar You will see a list of clients (applications). Choose/ Create the client for which you want to secure Next Application.
Fig 5.6.e: List of available clients After select your client, it will take you to the settings page
Fig 5.6.f: Client settings page Enter your application’s redirect URL in the Valid Redirect URIs field.
Fig 5.6.g: In client setting tab general settings fields Then under Capability config turn on Client authentication and save
Fig 5.6.h: In client setting tab capability config options You will now see a new tab enabled, called Credentials.
Fig 5.6.i: Client settings tab Navigate to the Credentials tab, where you can view and copy the Client Secret.
Fig 5.6.j: Navigating to Credentials tab With the ZTrust configuration complete, we can now move on to the Next.js Application side of the setup.
Step 2: Set up Next.js Appication
Install NextAuth
npm install next-auth
Create the Auth Route File: /pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth"; import OAuthProvider from "next-auth/providers/oauth"; const authOptions = { providers: [ OAuthProvider({ id: "ztrust", name: "ztrust", type: "oauth", version: "2.0", clientId: process.env.ZTRUST_CLIENT_ID, clientSecret: process.env.ZTRUST_CLIENT_SECRET, authorization: { url: `${process.env.ZTRUST_ISSUER}/protocol/openid-connect/auth`, params: { scope: "openid profile email", }, }, token: `${process.env.ZTRUST_ISSUER}/protocol/openid-connect/token`, userinfo: `${process.env.ZTRUST_ISSUER}/protocol/openid-connect/userinfo`, checks: ["pkce", "state"], profile(profile) { return { id: profile.sub, name: profile.name, email: profile.email, image: profile.picture, }; }, }), ], session: { strategy: "jwt", }, callbacks: { async jwt({ token, account, user }) { if (account) { token.accessToken = account.access_token; } return token; }, async session({ session, token }) { session.accessToken = token.accessToken; return session; }, }, }; export default NextAuth(authOptions);
Set Up Environment Variables .env.local:
NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=super-secret-random-string ZTRUST_CLIENT_ID=your-client-id ZTRUST_CLIENT_SECRET=your-client-secret ZTRUST_ISSUER=https://your-ztrust-domain/realms/your-realm
Make sure ZTrust client:
Is confidential
Has Standard Flow Enabled
Has Valid Redirect URIs set to: http://localhost:3000/api/auth/callback/ztrust
Test It Visit: http://localhost:3000/api/auth/signin
You should see a "Sign in with ZTrust" button.
Protect a Page
// pages/protected.tsx import { useSession, signIn } from "next-auth/react"; import { useEffect } from "react"; export default function ProtectedPage() { const { data: session, status } = useSession(); useEffect(() => { if (status === "unauthenticated") { signIn("ztrust"); // Optional: force ZTrust login } }, [status]); if (status === "loading") return <p>Loading...</p>; return ( <div> <h1>Protected Page</h1> <p>Welcome, {session?.user?.name}</p> </div> ); }
Last updated