Zum Inhalt springen

JWK-Auth-Middleware ​

Die JWK-Auth-Middleware authentifiziert Anfragen, indem sie Tokens mit JWK (JSON Web Key) überprüft. Sie prüft den Header Authorization sowie weitere konfigurierte Quellen, etwa Cookies, falls angegeben. Sie überprüft Tokens anhand der angegebenen keys, ruft bei Angabe von jwks_uri Schlüssel von dort ab und unterstützt bei gesetzter Option cookie das Extrahieren von Tokens aus Cookies.

Was diese Middleware überprüft ​

Für jedes Token führt jwk() Folgendes aus:

  • Liest und überprüft das Format des JWT-Headers.
  • Verlangt einen Header kid und sucht anhand von kid einen passenden Schlüssel.
  • Lehnt symmetrische Algorithmen (HS256, HS384, HS512) ab.
  • Verlangt, dass der Header alg in der konfigurierten Positivliste alg enthalten ist.
  • Wenn ein passender JWK ein Feld alg enthält, muss es mit dem JWT-Header alg übereinstimmen.
  • Überprüft die Token-Signatur mit dem passenden Schlüssel.
  • Prüft standardmäßig zeitbasierte Claims: nbf, exp und iat.

Die optionale Prüfung von Claims lässt sich mit der Option verification konfigurieren:

  • iss: Prüft den Aussteller, wenn angegeben.
  • aud: Prüft die Zielgruppe, wenn angegeben.

Wenn du über diese Prüfungen hinaus weitere Token-Prüfungen benötigst, etwa eigene Autorisierungsregeln auf Anwendungsebene, füge nach jwk() deine eigene Middleware hinzu.

Info

Der vom Client gesendete Authorization-Header muss ein angegebenes Authentifizierungsschema enthalten.

Beispiel: Bearer my.token.value oder Basic my.token.value

Import ​

ts
import { Hono } from 'hono'
import { jwk } from 'hono/jwk'
import { verifyWithJwks } from 'hono/jwt'

Verwendung ​

ts
const app = new Hono()

app.use(
  '/auth/*',
  jwk({
    jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
    alg: ['RS256'],
  })
)

app.get('/auth/page', (c) => {
  return c.text('You are authorized')
})

Nutzlast abrufen:

ts
const app = new Hono()

app.use(
  '/auth/*',
  jwk({
    jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
    alg: ['RS256'],
  })
)

app.get('/auth/page', (c) => {
  const payload = c.get('jwtPayload')
  return c.json(payload) // eg: { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
})

Anonymer Zugriff:

ts
const app = new Hono()

app.use(
  '/auth/*',
  jwk({
    jwks_uri: (c) =>
      `https://${c.env.authServer}/.well-known/jwks.json`,
    alg: ['RS256'],
    allow_anon: true,
  })
)

app.get('/auth/page', (c) => {
  const payload = c.get('jwtPayload')
  return c.json(payload ?? { message: 'hello anon' })
})

verifyWithJwks außerhalb von Middleware verwenden ​

Mit der Hilfsfunktion verifyWithJwks kannst du JWTs auch außerhalb von Honos Middleware-Kontext überprüfen, etwa in SvelteKit-SSR-Seiten oder anderen serverseitigen Umgebungen:

ts
const id_payload = await verifyWithJwks(
  id_token,
  {
    jwks_uri: 'https://your-auth-server/.well-known/jwks.json',
    allowedAlgorithms: ['RS256'],
  },
  {
    cf: { cacheEverything: true, cacheTtl: 3600 },
  }
)

Anfrageoptionen zum Abrufen von JWKS konfigurieren ​

Um den Abruf von JWKS aus jwks_uri zu konfigurieren, übergib fetch-Anfrageoptionen als zweites Argument von jwk().

Dieses Argument ist ein RequestInit und wird ausschließlich für die Anfrage zum Abrufen von JWKS verwendet.

ts
const app = new Hono()

app.use(
  '/auth/*',
  jwk(
    {
      jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
      alg: ['RS256'],
    },
    {
      headers: {
        Authorization: 'Bearer TOKEN',
      },
    }
  )
)

Optionen ​

required alg: AsymmetricAlgorithm[] ​

Ein Array erlaubter asymmetrischer Algorithmen zur Token-Prüfung.

Verfügbare Typen sind RS256 | RS384 | RS512 | PS256 | PS384 | PS512 | ES256 | ES384 | ES512 | EdDSA.

optional keys: HonoJsonWebKey[] | (c: Context) => Promise<HonoJsonWebKey[]> ​

Die Werte deiner öffentlichen Schlüssel oder eine Funktion, die sie zurückgibt. Die Funktion erhält das Context-Objekt.

optional jwks_uri: string | (c: Context) => Promise<string> ​

Wenn gesetzt, wird versucht, JWKs von dieser URI abzurufen. Erwartet wird eine JSON-Antwort mit keys, die den bereits über die Option keys angegebenen Schlüsseln hinzugefügt werden. Du kannst auch eine Callback-Funktion übergeben, um die JWKS-URI dynamisch anhand des Context festzulegen.

optional allow_anon: boolean ​

Bei true dürfen Anfragen ohne gültiges Token die Middleware passieren. Mit c.get('jwtPayload') kannst du prüfen, ob die Anfrage authentifiziert ist. Der Standardwert ist false.

Wenn gesetzt, wird mit diesem Wert als Schlüssel ein Wert aus dem Cookie-Header abgerufen und anschließend als Token überprüft.

optional headerName: string ​

Der Name des Headers, in dem nach dem JWT gesucht wird. Der Standardwert ist Authorization.

optional realm: string ​

Der Schutzbereich, der durch den Parameter realm im Challenge-Header WWW-Authenticate beschrieben wird, der bei 401-Antworten zurückgegeben wird. Der Standardwert ist die Anfrage-URL.

optional verification: VerifyOptions ​

Konfiguriert die Claim-Prüfung zusätzlich zur Signaturprüfung:

optional VerifyOptions.iss: string | RegExp ​

Der erwartete Aussteller zur Token-Prüfung. Wenn nicht gesetzt, wird der Claim iss nicht geprüft.

optional VerifyOptions.aud: string | string[] | RegExp ​

Die erwartete Zielgruppe zur Token-Prüfung. Wenn gesetzt, muss das Token einen Claim aud enthalten und mindestens einer der Zielgruppenwerte muss übereinstimmen.

optional VerifyOptions.nbf: boolean ​

Der Claim nbf (frühester Gültigkeitszeitpunkt) wird geprüft, wenn er vorhanden und diese Option auf true gesetzt ist. Der Standardwert ist true.

optional VerifyOptions.iat: boolean ​

Der Claim iat (Ausstellungszeitpunkt) wird geprüft, wenn er vorhanden und diese Option auf true gesetzt ist. Der Standardwert ist true.

optional VerifyOptions.exp: boolean ​

Der Claim exp (Ablaufzeitpunkt) wird geprüft, wenn er vorhanden und diese Option auf true gesetzt ist. Der Standardwert ist true.

Veröffentlicht unter der MIT-Lizenz.