feat(auth): validate mapped groups through Authentik

This commit is contained in:
2026-08-17 10:44:56 +02:00
parent 33ae7cfdc2
commit f0ae680671
9 changed files with 669 additions and 2 deletions
+33 -1
View File
@@ -40,6 +40,14 @@ export class OidcProviderUnavailableError extends OidcProtocolError {
}
}
/** The discovery document resolved, but its signed-token key set could not be certified. */
export class OidcJwksUnavailableError extends OidcProtocolError {
constructor() {
super("oidc_jwks_unreachable");
this.name = "OidcJwksUnavailableError";
}
}
export interface OidcProtocolOptions {
issuer: string;
clientId: string;
@@ -419,6 +427,24 @@ async function verifyIdTokenSignature(
}
}
async function verifyJwksAvailability(
config: Configuration,
transport: BoundedOidcTransport,
jwksTimeoutMs: number,
signal: AbortSignal,
): Promise<void> {
const metadata = config.serverMetadata();
if (!text(metadata.jwks_uri, 2048)) throw new OidcProtocolError();
const response = await transport.request(
httpsEndpoint(metadata.jwks_uri),
{ headers: { accept: "application/json" }, redirect: "manual", signal },
{ timeoutMs: jwksTimeoutMs, requireSuccess: true },
);
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await response.arrayBuffer()));
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)
|| !Array.isArray((parsed as { keys?: unknown }).keys)) throw new OidcProtocolError();
}
export function createOidcProtocol(options: OidcProtocolOptions): OidcProtocol {
const issuerUrl = configuredHttpsUrl(options.issuer);
const callbackUrl = configuredCallbackUrl(options.callbackUrl);
@@ -498,7 +524,13 @@ export function createOidcProtocol(options: OidcProtocolOptions): OidcProtocol {
},
async diagnose(signal) {
signal.throwIfAborted();
await configuration();
const config = await configuration();
signal.throwIfAborted();
try {
await verifyJwksAvailability(config, transport, jwksTimeoutMs, signal);
} catch {
throw new OidcJwksUnavailableError();
}
signal.throwIfAborted();
},
};