Le tue API
Un’app può chiedere un token di accesso per una delle tue API. Riceve un JWT firmato il cui destinatario è quell’API e nient’altro, e la tua API lo verifica con le chiavi pubblicate dal tuo ambiente, senza chiamare Usher. Un token per un’API non serve a nulla con un’altra.
Dai un nome all’API
In Usher Console, apri l’ambiente, poi Applicazioni → Le tue API → Aggiungi un’API. Assegnale un nome e un identificatore: un indirizzo https://, come https://api.example.com, o un URN, come urn:example:api:notes. L’identificatore è ciò che l’app richiede e ciò che indica il claim aud del token (RFC 8707).
Poi assegna l’API alle app che la chiamano: API in ogni applicazione. Un’app riceve token solo per le API che le sono state assegnate, qualunque cosa chieda. Se rimuovi un’API, non vengono più emessi token per essa; quelli già emessi scadono nel giro di pochi minuti.
Richiedila
L’app aggiunge resource=<identifier> alla richiesta di autorizzazione e alle richieste di token. Gli SDK per dispositivi mobili lo fanno al posto tuo:
let usher = UsherClient(configuration: .init(
issuer: URL(string: "https://login.example.com")!,
clientID: "…",
redirectURI: URL(string: "com.example.notes:/oauth/callback")!,
resources: ["urn:example:api:notes"]))
var request = URLRequest(url: URL(string: "https://api.example.com/notes")!)
try await usher.authorize(&request) // Authorization: Bearer <a JWT for the Notes API>val usher = Usher.client(context, UsherConfiguration(
issuer = "https://login.example.com",
clientId = "…",
redirectUri = "com.example.notes:/oauth/callback",
resources = listOf("urn:example:api:notes")))Un’app che chiama due delle tue API può richiederle entrambe insieme; in quel caso il destinatario del token le elenca tutte e due.
Verificalo nella tua API
Verifica il token di ogni richiesta prima di fidarti di qualsiasi cosa contenga:
- La firma, con le chiavi al
jwks_uriindicato nel documento di discovery del tuo ambiente. Prendi l’algoritmo dalla chiave, mai dall’intestazione del token. isscorrisponde esattamente all’issuer del tuo ambiente. Fissalo nella tua configurazione; non leggerlo mai dal token.audinclude l’identificatore della tua API. (Con l’ambitoopenidelenca anche l’indirizzo userinfo del tuo ambiente.)typnell’intestazione èat+jwt, così un token ID non può essere spacciato per un token di accesso.expnon è passato. I token di accesso durano 10 minuti; gli SDK li rinnovano al posto tuo.
In Node.js, @usher/node fa tutto questo:
import { createVerifier } from '@usher/node'
const usher = await createVerifier({
issuer: 'https://login.example.com',
audience: 'urn:example:api:notes',
})
const claims = await usher.accessToken(bearerToken) // throws if any check failsIn ASP.NET Core:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o =>
{
o.Authority = "https://login.example.com"; // discovery and keys come from here
o.MapInboundClaims = false;
o.TokenValidationParameters = new()
{
ValidIssuer = "https://login.example.com",
ValidAudience = "urn:example:api:notes",
ValidTypes = ["at+jwt"],
};
});Cosa dice il token
| Claim | |
|---|---|
sub | La persona. Insieme a iss, la chiave con cui identificarla. |
client_id, azp | L’app che ha fatto la richiesta. |
scope | Ciò che la persona ha acconsentito che l’app possa fare. |
email, email_verified | Con l’ambito email: l’indirizzo della persona, e se Usher ha verificato che è suo. |
sid | La sua sessione di accesso. |
org | Con l’ambito organization: la sua organizzazione attiva e il suo ruolo. |
Le persone che conosci già
Se la tua API ha già degli account creati in precedenza, puoi trovare quello di una persona la prima volta che arriva con un token Usher: cercala per email, solo quando email_verified è true, e da quel momento conserva iss e sub nel suo account. Dopodiché, trovala tramite iss e sub, mai tramite l’email: un indirizzo può passare a qualcun altro, un subject mai.