WebSSO / Entra ID
Northwestern users authenticate via single sign-on. The starter supports two SSO providers through the northwestern-sysdev/laravel-soa package’s WebSSOAuthentication trait.
Providers:
- Microsoft Entra ID (formerly Azure AD) - OAuth2 authorization code flow directly to Microsoft
- Online Passport (agentless WebSSO) - Cookie-based SSO via OpenAM/ForgeRock, validated through Apigee
The starter auto-detects which provider to use based on your credentials (SsoProvider::configured()). Online Passport is used when WEBSSO_API_KEY is set or WEBSSO_STRATEGY is forgerock-direct; otherwise Entra ID is used when both AZURE_CLIENT_ID and AZURE_CLIENT_SECRET are set. Only that provider’s routes are registered, and sign-in, logout and config:validate all use it. When neither is configured, the sign-in page has no NetID button.
SSO is optional in the local environment, where the sign-in page offers Sign In As for the seeded demo users and config:validate skips the SSO check when no provider is configured. See Signing In Locally. Deployed environments always need a provider.
For a higher-level overview of all authentication methods, see the Authentication documentation.
How It Works (Entra ID)
Section titled “How It Works (Entra ID)”-
User clicks “Sign In with NetID”
The application redirects to Microsoft’s login endpoint via
WebSSOController@oauthRedirect. The OAuth2 authorization code flow goes directly tologin.microsoftonline.com, not through Apigee or ForgeRock. -
User authenticates with Microsoft
User enters their credentials.
-
Callback with token
Microsoft redirects back to
/auth/azure-ad/callbackvia POST with an authorization code. CSRF middleware is excluded for this route since the request originates from the identity provider. Thelaravel-soapackage exchanges the code for tokens and validates the ID token JWT using Microsoft’s signing keys. -
Directory Search lookup
WebSSOController::findUserByNetID()callsFindOrUpdateUserFromDirectoryto provision or update the user from Northwestern’s directory. This includes a 3-attempt retry with 500ms delays. If all retries fail, the user sees the 503 page (see Error Handling). -
Session established
The
laravel-soatrait logs the user in, then calls the starter’sauthenticated()hook, which finishes withSignIn::complete(), as every sign-in method does: a new session and CSRF token, aUserLoginRecord, and/, whereHomeControllersends them on to the app panel, unless they were headed for another page first. Single sign-on isn’t remembered past the session, since signing in again is usually silent.
How It Works (Online Passport)
Section titled “How It Works (Online Passport)”-
User clicks “Sign In with NetID”
The application redirects to ForgeRock’s login page via
WebSSOController@login. The user is sent to Northwestern’s Online Passport login portal. -
User authenticates with ForgeRock
User enters their NetID credentials (and completes MFA if Duo is enabled).
-
Cookie validation
After authentication, ForgeRock sets a
nussosession cookie. Thelaravel-soapackage validates this cookie by calling Northwestern’s agentless WebSSO API (via Apigee or directly against ForgeRock, depending on the configured strategy). -
Directory Search lookup
WebSSOController::findUserByNetID()callsFindOrUpdateUserFromDirectoryto provision or update the user, identical to the Entra ID flow. -
Session established
The
laravel-soatrait logs the user in, then calls the starter’sauthenticated()hook, which finishes withSignIn::complete(), as every sign-in method does: a new session and CSRF token, aUserLoginRecord, and/, whereHomeControllersends them on to the app panel, unless they were headed for another page first. Single sign-on isn’t remembered past the session, since signing in again is usually silent.
Routes
Section titled “Routes”Routes are defined in routes/auth.php. The Entra ID and Online Passport routes are registered only when that provider is configured; the shared logout route is always registered.
Entra ID Routes
Section titled “Entra ID Routes”| Method | URI | Controller | Name |
|---|---|---|---|
GET | /auth/azure-ad/redirect | WebSSOController@oauthRedirect | login-oauth-redirect |
POST | /auth/azure-ad/callback | WebSSOController@oauthCallback | login-oauth-callback |
GET | /auth/azure-ad/oauth-logout | WebSSOController@oauthLogout | login-oauth-logout |
Online Passport Routes
Section titled “Online Passport Routes”| Method | URI | Controller | Name |
|---|---|---|---|
GET | /auth/websso/login | WebSSOController@login | login-websso |
GET | /auth/websso/logout | WebSSOController@logout | login-websso-logout |
Shared Route
Section titled “Shared Route”| Method | URI | Controller | Name |
|---|---|---|---|
POST | /auth/logout | LogoutSelectionController | logout |
LogoutSelectionController asks SignIn::signOut(), which sends SSO users to the configured provider’s logout route. Local users, and SSO users when no provider is configured, are signed out locally.
Logout
Section titled “Logout”Entra ID Logout
Section titled “Entra ID Logout”The oauthLogout() method handles SSO session cleanup:
- Outside CI - Delegates to the
laravel-soatrait’soauthLogout()method, which clears the local session and then redirects to Entra ID’s logout endpoint. - CI environment - Skips the Entra redirect and performs a local-only logout to avoid external service dependencies.
Online Passport Logout
Section titled “Online Passport Logout”The logout() method (from the WebSSOAuthentication trait) redirects the user to ForgeRock’s logout endpoint to clear the nusso session cookie. The local session is invalidated before the redirect.
Error Handling
Section titled “Error Handling”If the Directory Search lookup fails after 3 retries during the SSO callback, the controller throws a ServiceDownError for ExternalService::DirectorySearch (directory-search). The exception renders itself: browser requests get the 503 page (resources/views/errors/503.blade.php), and API or JSON requests get a Problem Details 503 response with Retry-After: 60. The error is still reported to Sentry.
Entra ID Configuration
Section titled “Entra ID Configuration”Online Passport Configuration
Section titled “Online Passport Configuration”Setting WEBSSO_API_KEY (or using WEBSSO_STRATEGY=forgerock-direct) switches the starter from Entra ID to Online Passport. The login and logout buttons will automatically route through ForgeRock instead of Microsoft.
WEBSSO_STRATEGYapigeeSSO strategy (apigee or forgerock-direct)
WEBSSO_URL_BASEhttps://uat-nusso.it.northwestern.eduForgeRock base URL
WEBSSO_API_URL_BASEhttps://northwestern-prod.apigee.net/agentless-webssoAgentless WebSSO API URL (Apigee)
WEBSSO_API_KEYRequiredApigee API key for agentless WebSSO
WEBSSO_REALMnorthwesternWebSSO realm
WEBSSO_COOKIE_NAMEnussoWebSSO session cookie name
DUO_ENABLEDfalseEnable Duo MFA (sets auth tree to ldap-and-duo)
See the laravel-soa documentation for full details on configuring Online Passport.