OIDC validation & issuer fixes (#363)

* fix: validation and issuer checks

* feat: query param util

* fix: lint
This commit is contained in:
DecDuck
2026-03-01 10:25:55 +00:00
committed by GitHub
parent 14f4135071
commit 83516d83fd
3 changed files with 28 additions and 16 deletions
+3 -1
View File
@@ -30,7 +30,9 @@ class AuthManager {
(this.authProviders as any)[key] = object; (this.authProviders as any)[key] = object;
logger.info(`enabled auth: ${key}`); logger.info(`enabled auth: ${key}`);
} catch (e) { } catch (e) {
logger.warn((e as string).toString()); logger.warn(
`failed to enable auth ${key}: ${(e as string).toString()}`,
);
} }
} }
+18 -15
View File
@@ -12,28 +12,22 @@ import * as jose from "jose";
// import { inspect } from "util"; // import { inspect } from "util";
import sessionHandler from "../../session"; import sessionHandler from "../../session";
import type { SessionSearchTerms } from "../../session/types"; import type { SessionSearchTerms } from "../../session/types";
import { queryParamBuilder } from "../../utils/query";
// TODO: monitor https://github.com/goauthentik/authentik/issues/8751 for easier?? OIDC setup by end users // TODO: monitor https://github.com/goauthentik/authentik/issues/8751 for easier?? OIDC setup by end users
// Schema for OIDC well-known configuration // Schema for OIDC well-known configuration
const OIDCWellKnownV1 = type({ const OIDCWellKnownV1 = type({
issuer: "string.url.parse", issuer: "string",
authorization_endpoint: "string.url.parse", authorization_endpoint: "string.url.parse",
token_endpoint: "string.url.parse", token_endpoint: "string.url.parse",
userinfo_endpoint: "string.url.parse?", userinfo_endpoint: "string.url.parse",
jwks_uri: "string.url.parse", jwks_uri: "string.url.parse",
scopes_supported: "string[]?", scopes_supported: "string[]",
}); });
// Represents required OIDC configuration // Represents required OIDC configuration
interface OIDCConfiguration { type OIDCConfiguration = typeof OIDCWellKnownV1.infer;
issuer: URL;
authorization_endpoint: URL;
token_endpoint: URL;
userinfo_endpoint: URL;
jwks_uri: URL;
scopes_supported: string[];
}
interface OIDCAuthSessionOptions { interface OIDCAuthSessionOptions {
redirect: string | undefined; redirect: string | undefined;
@@ -241,7 +235,7 @@ export class OIDCManager {
token_endpoint: new URL(tokenEndpoint), token_endpoint: new URL(tokenEndpoint),
userinfo_endpoint: new URL(userinfoEndpoint), userinfo_endpoint: new URL(userinfoEndpoint),
scopes_supported: scopes.split(","), scopes_supported: scopes.split(","),
issuer: new URL(issuer), issuer: issuer,
jwks_uri: new URL(jwksEndpoint), jwks_uri: new URL(jwksEndpoint),
}; };
} }
@@ -294,7 +288,15 @@ export class OIDCManager {
this.oidcConfiguration.authorization_endpoint, this.oidcConfiguration.authorization_endpoint,
).toString(); ).toString();
const finalUrl = `${normalisedUrl}?client_id=${this.clientId}&redirect_uri=${encodeURIComponent(this.redirectUrl.toString())}&state=${stateKey}&response_type=code&scope=${encodeURIComponent(this.oidcConfiguration.scopes_supported.join(" "))}`; const queryParams = queryParamBuilder({
client_id: this.clientId,
redirect_uri: this.redirectUrl.toString(),
state: stateKey,
response_type: "code",
scope: this.oidcConfiguration.scopes_supported.join(" "),
});
const finalUrl = `${normalisedUrl}?${queryParams}`;
const session: OIDCAuthSession = { const session: OIDCAuthSession = {
redirectUrl: finalUrl, redirectUrl: finalUrl,
@@ -549,7 +551,8 @@ export class OIDCManager {
} }
} }
function isHttps(url: URL): boolean { function isHttps(url: URL | string): boolean {
if (url.protocol === "https:") return true; const parsedUrl = typeof url === "string" ? new URL(url) : url;
if (parsedUrl.protocol === "https:") return true;
else return false; else return false;
} }
+7
View File
@@ -0,0 +1,7 @@
export function queryParamBuilder(params: { [key: string]: string }) {
const list = Object.entries(params).map(
([key, value]) => `${key}=${encodeURIComponent(value)}`,
);
const str = list.join("&");
return str;
}