Webrizendocs
Integrate your app

Any OIDC stack

Webrizen SSO is a standard OpenID Connect provider, so any language or framework with an OIDC library can use it: Node, Python, PHP, Java, Go, .NET, mobile.

What every integration needs

SettingValue
Discovery URLhttps://accounts.webrizen.com/api/auth/.well-known/openid-configuration
Issuerhttps://accounts.webrizen.com/api/auth
FlowAuthorization code with PKCE (S256)
Scopesopenid profile email organization offline_access
Client authenticationclient_secret_basic (server apps) or none (SPA / mobile)
ID token signingRS256

Most libraries only need the discovery URL, client ID, client secret and redirect URI. Everything else is discovered automatically.

Node.js (Express)

server.js
import express from "express";
import session from "express-session";
import * as oidc from "openid-client";
 
const app = express();
app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false }));
 
const config = await oidc.discovery(
  new URL(process.env.WEBRIZEN_SSO_ISSUER),
  process.env.WEBRIZEN_SSO_CLIENT_ID,
  process.env.WEBRIZEN_SSO_CLIENT_SECRET,
);
const redirect_uri = `${process.env.APP_URL}/callback`;
 
app.get("/login", async (req, res) => {
  const code_verifier = oidc.randomPKCECodeVerifier();
  const state = oidc.randomState();
  req.session.oidc = { code_verifier, state };
  const url = oidc.buildAuthorizationUrl(config, {
    redirect_uri,
    scope: "openid profile email organization",
    code_challenge: await oidc.calculatePKCECodeChallenge(code_verifier),
    code_challenge_method: "S256",
    state,
  });
  res.redirect(url.href);
});
 
app.get("/callback", async (req, res) => {
  const { code_verifier, state } = req.session.oidc ?? {};
  const tokens = await oidc.authorizationCodeGrant(
    config,
    new URL(req.originalUrl, process.env.APP_URL),
    { pkceCodeVerifier: code_verifier, expectedState: state },
  );
  const claims = tokens.claims();
  req.session.user = { id: claims.sub, email: claims.email, name: claims.name, org: claims.org };
  res.redirect("/");
});

Python (Django)

Using mozilla-django-oidc:

settings.py
ISSUER = "https://accounts.webrizen.com/api/auth"
 
OIDC_RP_CLIENT_ID = env("WEBRIZEN_SSO_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = env("WEBRIZEN_SSO_CLIENT_SECRET")
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_RP_SCOPES = "openid profile email organization"
OIDC_USE_PKCE = True
 
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{ISSUER}/oauth2/authorize"
OIDC_OP_TOKEN_ENDPOINT = f"{ISSUER}/oauth2/token"
OIDC_OP_USER_ENDPOINT = f"{ISSUER}/oauth2/userinfo"
OIDC_OP_JWKS_ENDPOINT = f"{ISSUER}/jwks"

Organization data arrives in the userinfo response under org. Read it in a custom OIDCAuthenticationBackend.update_user / create_user to map roles onto your models.

PHP, Java, Go, .NET

Pick your framework's maintained OIDC client (for example Spring Security OAuth2 Client, coreos/go-oidc, Microsoft.AspNetCore.Authentication.OpenIdConnect, or a Laravel/Symfony OIDC package), then configure it with the values in the table above.

Doing it by hand

If you must, the flow is three HTTP requests:

# 1. Send the browser to:
https://accounts.webrizen.com/api/auth/oauth2/authorize?response_type=code
  &client_id=CLIENT_ID&redirect_uri=REDIRECT_URI
  &scope=openid%20profile%20email%20organization
  &state=RANDOM&code_challenge=S256_CHALLENGE&code_challenge_method=S256
 
# 2. Exchange the returned code (server-side):
curl -u CLIENT_ID:CLIENT_SECRET https://accounts.webrizen.com/api/auth/oauth2/token \
  -d grant_type=authorization_code -d code=CODE \
  -d redirect_uri=REDIRECT_URI -d code_verifier=VERIFIER
 
# 3. Fetch the user:
curl -H "Authorization: Bearer ACCESS_TOKEN" \
  https://accounts.webrizen.com/api/auth/oauth2/userinfo
Validate ID tokens properly

Verify the signature against the JWKS, and check iss, aud (your client ID), exp and the nonce if you sent one. Libraries do this for you, which is the main reason to use one.

Single-page and mobile apps

Register the app as Single-page app or Mobile / desktop. These get no client secret and rely on PKCE. Use a library such as oidc-client-ts (browser) or AppAuth (iOS/Android). Keep tokens in memory where possible, and prefer a backend-for-frontend when your app has a server.