דילוג לתוכן
תיעוד · כל ספריית OIDC

התחלה מהירה: כל ספריית OIDC

Usher הוא ספק OpenID Connect סטנדרטי. אם יש לשפה שלך לקוח OIDC מוסמך, כבר יש לך כל מה שצריך: מכוונים אותו למסמך הגילוי של הסביבה שלך ומשתמשים בזרימת קוד ההרשאה עם PKCE.

ההגדרות

הגדרהערך
מנפיקhttps://<handle>.usherid.com
כתובת הגילויhttps://<handle>.usherid.com/.well-known/openid-configuration
זרימהקוד הרשאה (response_type=code)
PKCEחובה, code_challenge_method=S256
היקפי הרשאותopenid profile email offline_access
אימות הלקוחלפי הרשימה ב-token_endpoint_auth_methods_supported

הכינוי של הסביבה שלך מופיע ב-Usher Console, ליד המנפיק שלה. סביבות פיתוח מקבלות כינוי אקראי, כמו wise-otter-42; לסביבות ייצור יש הכינוי שבחרת. סביבת ייצור יכולה גם להיות בדומיין שלך, כמו login.acme.com: אז הוא המנפיק שלה, אחרי שמכוונים את הדומיין ל-Usher עם רשומת CNAME.

קריאת מסמך הגילוי

כל נקודת קצה וכל מפתח שהלקוח שלך צריך מופיעים כאן. עדיף לתת לספרייה לקרוא אותו, במקום להעתיק כתובות לתוך הקוד.

מסוף
curl -s https://acme.usherid.com/.well-known/openid-configuration | jq
תגובה (מקוצרת)
{
  "issuer": "https://acme.usherid.com",
  "authorization_endpoint": "https://acme.usherid.com/api/auth/oauth2/authorize",
  "token_endpoint": "https://acme.usherid.com/api/auth/oauth2/token",
  "userinfo_endpoint": "https://acme.usherid.com/api/auth/oauth2/userinfo",
  "jwks_uri": "https://acme.usherid.com/api/auth/jwks",
  "introspection_endpoint": "https://acme.usherid.com/api/auth/oauth2/introspect",
  "revocation_endpoint": "https://acme.usherid.com/api/auth/oauth2/revoke",
  "end_session_endpoint": "https://acme.usherid.com/api/auth/oauth2/end-session",
  "scopes_supported": ["openid", "profile", "email", "offline_access"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token", "client_credentials"],
  "code_challenge_methods_supported": ["S256"]
}

הזרימה

שליחת האדם לנקודת הקצה של ההרשאה

יוצרים verifier אקראי של PKCE ושומרים אותו, יחד עם state אקראי, במקום שרק הסשן של הדפדפן הזה יכול להגיע אליו (קובץ Cookie מסוג httpOnly לזמן קצר מתאים לזה). אחר כך מפנים עם response_type=code, עם ה-client_id וה-redirect_uri שלך, עם היקפי ההרשאות שלמעלה, עם ה-state ועם ה-code_challenge מסוג S256 של ה-verifier שלך.

נותנים להם להתחבר

מכאן ה-Lobby ממשיך: הוא מציין את שם האפליקציה שלך, מציע את שיטות ההתחברות שהסביבה שלך מתירה, ומבקש הסכמה בפעם הראשונה.

בדיקת ה-callback

Usher מפנה ל-redirect_uri שלך עם code ו-state. יש לדחות את התגובה אם ה-state לא תואם לזה ששמרת. הקוד הוא לשימוש יחיד ותקף לחמש דקות.

החלפת הקוד באסימונים

מהשרת שלך, שולחים את הקוד ואת ה-verifier של PKCE לנקודת הקצה של האסימונים:

בקשת אסימון
curl -s -X POST https://acme.usherid.com/api/auth/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code="$CODE" \
-d redirect_uri=https://app.acme.example/callback \
-d code_verifier="$CODE_VERIFIER"

אימות אסימון הזהות

בודקים את החתימה שלו מול המפתחות ב-jwks_uri, ושה-iss הוא המנפיק שלך, שה-aud הוא מזהה הלקוח שלך ושה-exp עוד לא עבר. הספרייה שלך עושה את זה בשבילך; כדאי לוודא שהבדיקה לא כבויה.

ב-Node.js

openid-client עושה את כל מה שלמעלה, כולל האימות:

openid-client
import * as client from 'openid-client'

// discovery: every endpoint and key comes from the issuer
const config = await client.discovery(
  new URL('https://acme.usherid.com'),
  process.env.USHER_CLIENT_ID!,
  process.env.USHER_CLIENT_SECRET!,
)

// 1. send them to the Lobby, with PKCE (S256) and a state to check later
const codeVerifier = client.randomPKCECodeVerifier()
const state = client.randomState()
const url = client.buildAuthorizationUrl(config, {
  redirect_uri: 'https://app.acme.example/callback',
  scope: 'openid profile email offline_access',
  code_challenge: await client.calculatePKCECodeChallenge(codeVerifier),
  code_challenge_method: 'S256',
  state,
})
// keep codeVerifier and state in a short-lived httpOnly cookie, then redirect to url

// 2. back at /callback: swap the code for tokens
const tokens = await client.authorizationCodeGrant(config, new URL(request.url), {
  pkceCodeVerifier: codeVerifier,
  expectedState: state,
})
const { sub, email, name } = tokens.claims()!

בשפות אחרות

כל הספריות הנפוצות האלה מדברות OpenID Connect סטנדרטי ועובדות עם Usher בלי שום דבר ייחודי ל-Usher:

שפהספרייה
PythonAuthlib
Gocoreos/go-oidc עם golang.org/x/oauth2
JavaSpring Security OAuth 2.0 Client
.NETMicrosoft.AspNetCore.Authentication.OpenIdConnect
Rubyomniauth_openid_connect
PHPjumbojett/openid-connect-php

להישאר מחוברים

עם ה-scope offline_access, תגובת האסימון כוללת אסימון רענון. משתמשים בו עם grant_type=refresh_token כדי לקבל אסימון גישה חדש כשהקודם פג. אסימוני רענון מתחלפים: כל שימוש מחזיר אסימון חדש, והקודם מפסיק לעבוד.

התנתקות

קודם מנקים את הסשן שלך, ואז מפנים ל-end_session_endpoint עם post_logout_redirect_uri (ועם id_token_hint אם יש), כדי שגם ה-Lobby ישכח את האדם.