Vos propres API
Une app peut demander un jeton d’accès pour l’une de vos API. Elle reçoit un JWT signé dont l’audience est cette API et rien d’autre, et votre API le vérifie avec les clés publiées de votre environnement, sans appeler Usher. Un jeton destiné à une API ne sert à rien auprès d’une autre.
Nommer l’API
Dans Usher Console, ouvrez l’environnement, puis Applications → Vos API → Ajouter une API. Donnez-lui un nom et un identifiant : une adresse https://, comme https://api.example.com, ou un URN, comme urn:example:api:notes. L’identifiant est ce que l’app demande et ce qu’indique la revendication aud du jeton (RFC 8707).
Associez ensuite l’API aux apps qui l’appellent : API dans chaque application. Une app n’obtient des jetons que pour les API qui lui ont été associées, quoi qu’elle demande. Si vous retirez une API, plus aucun jeton n’est émis pour elle ; ceux déjà émis expirent en quelques minutes.
La demander
L’app ajoute resource=<identifier> à sa demande d’autorisation et à ses requêtes de jeton. Les SDK mobiles le font pour vous :
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")))Une app qui appelle deux de vos API peut demander les deux à la fois ; l’audience du jeton les mentionne alors toutes les deux.
La vérifier dans votre API
Vérifiez le jeton de chaque requête avant de vous fier à quoi que ce soit qu’il contient :
- La signature, avec les clés du
jwks_uriindiqué dans le document de découverte de votre environnement. Prenez l’algorithme dans la clé, jamais dans l’en-tête du jeton. issest exactement l’émetteur de votre environnement. Fixez-le dans votre configuration ; ne le lisez jamais dans le jeton.audcontient l’identifiant de votre API. (Avec la portéeopenid, la liste comprend aussi l’adresse userinfo de votre environnement.)typdans l’en-tête vautat+jwt, pour qu’un jeton d’ID ne puisse pas passer pour un jeton d’accès.expn’est pas dépassé. Les jetons d’accès durent 10 minutes ; les SDK les actualisent pour vous.
Avec Node.js, @usher/node s’occupe de tout :
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 failsAvec 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"],
};
});Ce que dit le jeton
| Revendication | |
|---|---|
sub | La personne. Associé à iss, c’est la clé sous laquelle la conserver. |
client_id, azp | L’app qui a fait la demande. |
scope | Ce que la personne a autorisé l’app à faire. |
email, email_verified | Avec la portée email : l’adresse de la personne, et si Usher a vérifié qu’elle lui appartient. |
sid | Sa session de connexion. |
org | Avec la portée organization : son organisation active et son rôle. |
Les personnes que vous connaissez déjà
Si votre API a déjà des comptes existants, vous pouvez retrouver celui d’une personne la première fois qu’elle arrive avec un jeton Usher : cherchez-la par email, uniquement si email_verified vaut true, puis enregistrez iss et sub sur son compte. Par la suite, retrouvez-la par iss et sub, jamais par adresse e-mail : une adresse peut changer de mains, un sujet jamais.