Dokümanlar menüsü
SSO (OAuth/OIDC/JWT)
Kurumsal kimlik sağlayıcıdan (IdP/gateway) gelen isteği Principal'a çözen SSO sağlayıcısı; createEnterpriseAuth kimlik zincirinde userStore ve fallback'ten önce çalışır.
Ne işe yarar / ne zaman kullanılır#
Kurumsal dağıtımlarda kimlik doğrulama genelde GNL'in dışında, bir IdP/gateway (Okta, Azure AD, Auth0, bir API gateway...) tarafından zaten yapılmıştır ve istek GNL'e ulaştığında üzerinde imzalı bir JWT taşır. createJwtSso tam olarak bu senaryo için: redirect/login akışını yürütmez — gelen isteğin Authorization: Bearer <jwt> (ya da özel bir header) içindeki JWT'yi imza + süre (exp) + iss/aud bakımından doğrular ve claim'lerden bir Principal türetir.
Bunun yanında iki adlandırılmış sağlayıcı gerçek redirect+token akışını tam olarak yürütür: createAuth0Sso (OIDC authorization-code — code'u /oauth/token'da id_token'a değiştirir, id_token'ı Auth0'ın JWKS'inden türetilen RS256 public key ile verifyJwt üzerinden doğrular; iss/aud zorunludur) ve createWorkOsSso (WorkOS SSO API — code'u /sso/token'da profile'a değiştirir). Bugün üründe kullanılabilir üç gerçek yol vardır: createJwtSso (yukarı akıştan doğrulanmış JWT), createAuth0Sso ve createWorkOsSso.
Kurulum / import#
import { createJwtSso, createAuth0Sso, createWorkOsSso, createEnterpriseAuth } from '@gnldev/auth-ee';@gnldev/auth-ee paralı (Enterprise) bir pakettir — geçerli bir lisans anahtarı olmadan createEnterpriseAuth otomatik olarak fallback'e düşer (bkz. aşağıdaki uyarı). SsoProvider arayüzü, ücretsiz @gnldev/auth'un AuthProvider sözleşmesini genişletmez — yalnızca createEnterpriseAuth'a sso seçeneği olarak verilir.
Adım adım kullanım#
1. createJwtSso'ya doğrulama parametrelerini verin — HS256 için secret, RS256/Ed25519 için publicKey (PEM ya da base64url DER/spki); ikisinden biri zorunludur, hiçbiri verilmezse fabrika hata fırlatır. issuer ve audience da zorunludur: bunlar olmadan aynı IdP'nin başka bir uygulama için imzaladığı token burada giriş yapabilirdi. Birini bilerek atlamak için false verin. exp'i maxTtlSec'ten (varsayılan bir gün) daha uzakta olan token reddedilir. Aksini söylemedikçe her giriş bir kullanıcıdır (kind: subject): token'daki bir kind claim'i tek başına okunmaz; okunsaydı, sizin hiç yapılandırmadığınız bir claim'i kontrol eden kişi kendi yetkisini kendisi seçerdi. Personeli işaretlemek için kindOf verin — doğrulanmış claim'leri (WorkOS'ta profili) alır ve bir kind döner, ör. kindOf: (claims) => ((claims.groups as string[] | undefined)?.includes('gnl-ops') ? 'operator' : 'subject'). Üç sağlayıcı da bunu alır; hata atan ya da geçerli bir kind dönmeyen kindOf subject verir:
const sso = createJwtSso({
publicKey: process.env.SSO_JWT_PUBLIC_KEY, // the public key taken from Okta / Azure AD / Auth0 JWKS
issuer: 'https://idp.example.com',
audience: 'gnl-api',
// claimMap: { id: 'sub', roles: 'roles', orgId: 'orgId' } (default)
});2. sso'yu createEnterpriseAuth'a verin — kimlik zincirinde önce SSO denenir, sonra journal-destekli userStore, en son ücretsiz fallback:
const auth = createEnterpriseAuth({
licenseKey: process.env.GNL_LICENSE_KEY,
sso,
fallback: roleAuth({ admin: { token: process.env.GNL_ADMIN_TOKEN } }),
});
app.mount('/api', createRestApi(config, { title: 'GNL API', auth }));3. İstemci, IdP'den aldığı JWT'yi normal şekilde gönderir; createJwtSso isteği doğrudan principalFromRequest(c) ile çözer (bu, createEnterpriseAuth'un authenticate adımı içinde otomatik çağrılır — host kodunda ekstra bir şey yapmaya gerek yoktur):
curl -s http://localhost:3001/api/agents \
-H 'authorization: Bearer <jwt-signed-by-your-idp>'JWT geçersiz, süresi dolmuş ya da bozuksa principalFromRequest asla fırlatmaz — sessizce null döner ve zincir bir sonraki adıma (userStore, ardından fallback) düşer.
4. createAuth0Sso — Auth0 tenant'ınızın domain/clientId/clientSecret/redirectUri'sini verin; authorizeUrl ile /authorize'a yönlendirir, handleCallback code'u /oauth/token'da id_token'a değiştirip Auth0'ın JWKS'i (.well-known/jwks.json) ile RS256 doğrular (iss/aud zorunlu):
const auth0 = createAuth0Sso({
domain: 'acme.eu.auth0.com',
clientId: process.env.AUTH0_CLIENT_ID!,
clientSecret: process.env.AUTH0_CLIENT_SECRET!,
redirectUri: 'https://app.example.com/callback',
validateState: (state) => checkStateAgainstSession(state), // CSRF — required by handleCallback
});
const auth = createEnterpriseAuth({ licenseKey, sso: auth0, fallback });JWKS ağ çağrısı bir jwksTtlMs (varsayılan 10 dakika) in-memory önbelleğe alınır — principalFromRequest her istekte çalıştığından bu önbellek olmadan her istek bir JWKS fetch'i olurdu; önbellek bayatken fetch başarısız olursa (Auth0 kesintisi) bayat kopya en fazla jwksMaxStaleMs (varsayılan 1 saat; stale-while-error) kullanılmaya devam eder. Bu süreden sonra doğrulama kapalı hata verir. handleCallback validateState ister, o olmadan hata fırlatır.
5. createWorkOsSso — WorkOS SSO API'sini kullanır; handleCallback code'u /sso/token'da profile'a değiştirip Principal türetir (WorkOS profili zaten WorkOS tarafından imzalı/doğrulanmış gelir — ayrı bir JWKS doğrulaması gerekmez):
const workos = createWorkOsSso({
clientId: process.env.WORKOS_CLIENT_ID!,
apiKey: process.env.WORKOS_API_KEY!,
redirectUri: 'https://app.example.com/callback',
validateState: (state) => checkStateAgainstSession(state),
});createWorkOsSso YALNIZCA handleCallback tabanlı login akışını kurar — WorkOS'ta istek üzerinde taşınan doğrulanabilir bir bearer token sözleşmesi yoktur, bu yüzden principalFromRequest her zaman null döner. Bunu tek başına createEnterpriseAuth({ sso: workos }) olarak bağlarsanız SSO adımı HER istekte null döner ve korunan uçlar sessizce anonime düşer — genelde istenen davranış budur değildir. Doğru desen: WorkOS callback'inden dönen Principal ile kendi oturum JWT'nizi basıp createJwtSso ile birleştirmek:const session = createJwtSso({ secret: process.env.SESSION_SECRET!, issuer: 'my-app', audience: false });
// callback ucunda:
const principal = await workos.handleCallback(c);
const jwt = signMySessionJwt(principal); // a short-lived session JWT you sign yourself
// hand it to the client via Set-Cookie or the body
// sonraki istekler:
const auth = createEnterpriseAuth({ licenseKey, sso: session, fallback });API referansı#
createJwtSsoJwtSsoOptions → SsoProvider. Yukarı akıştan gelen JWT'yi imza+exp+iss/aud ile doğrular, claim'lerden Principal türetir (redirect/login akışı yürütmez).
createAuth0SsoAuth0SsoOptions → SsoProvider. OIDC authorization-code: code→id_token değişimi + Auth0 JWKS'iyle RS256 doğrulama (iss/aud zorunlu), TTL cache'li JWKS (bayat kopya en fazla jwksMaxStaleMs), handleCallback'in zorunlu tuttuğu validateState CSRF kancası.
Auth0SsoOptions{ domain, clientId, clientSecret, redirectUri, scope?, claimMap?, kindOf?, validateState?, fetch?, jwks?, jwksTtlMs?, jwksMaxStaleMs?, now? } — createAuth0Sso yapılandırması.
createWorkOsSsoWorkOsSsoOptions → SsoProvider. WorkOS SSO API: code→profile değişimi ile Principal türetir. principalFromRequest DAİMA null döner — yalnız login akışı kurar, createJwtSso ile birleştirilmelidir.
WorkOsSsoOptions{ clientId, kindOf?, apiKey, redirectUri, organization?, connection?, validateState?, fetch? } — createWorkOsSso yapılandırması.
SsoProvider{ authorizeUrl(state), handleCallback(c), principalFromRequest(c) } — createEnterpriseAuth'un sso seçeneği bu sözleşmeyi bekler.
JwtSsoOptionssecret (HS256) ya da publicKey (RS256/Ed25519, PEM veya base64url DER/spki), issuer ve audience (zorunlu; false biri atlar), maxTtlSec?, claimMap?, kindOf?, onClaims?, header? — createJwtSso'nun yapılandırması. kindOf(claims) personeli işaretler (varsayılan: her giriş bir subject'tir); onClaims doğrulanmış claim'leri alır.
@gnldev/auth-ee paralı bir katmandır: geçerli bir licenseKey olmadan createEnterpriseAuth uyarı loglayıp fallback'e düşer (sso hiç devreye girmez). Bir licenseKey verildiğinde failClosed varsayılan olarak true'dur: geçersiz anahtar boot'ta hata fırlatır, lisans süresi dolunca her istek 403 ile reddedilir. failClosed: false bunun yerine fallback'e düşer.alg'a körü körüne güvenmez: beklenen algoritma secret/publicKey anahtar tipinden (HS256 / RS256 / EdDSA) türetilir ve header'daki değerle çapraz kontrol edilir. Ayrıca exp claim'i olmayan ya da süresi dolmuş token'lar her zaman reddedilir.sso → userStore → fallback. Böylece SSO devredeyken bile boş bir kullanıcı deposuyla operatör bootstrap token'ı ile girip ilk kullanıcıları oluşturabilirsiniz.