Fix OIDC token exchange behind HTTPS reverse proxy (#162)
* Initial plan * Fix OIDC callback URL construction for HTTPS reverse proxy - Replace hardcoded http:// URL with OIDC_REDIRECT_URI from environment - Build complete callback URL with query parameters for proper validation - Fixes token exchange 401 errors when running behind HTTPS reverse proxy Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> * Update OIDC_REDIRECT_URI documentation to clarify full URL requirement Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> * fix: format oidc.ts to pass biome check --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> Co-authored-by: Daniel Volz <mail@danielvolz.org>
This commit is contained in:
@@ -213,7 +213,7 @@ Generate secrets with: `openssl rand -hex 32`
|
||||
| `OIDC_ISSUER_URL` | — | OIDC provider URL |
|
||||
| `OIDC_CLIENT_ID` | — | Client ID from OIDC provider |
|
||||
| `OIDC_CLIENT_SECRET` | — | Client secret from OIDC provider |
|
||||
| `OIDC_REDIRECT_URI` | — | Callback URL |
|
||||
| `OIDC_REDIRECT_URI` | — | Full callback URL (e.g., `https://your-domain.com/api/auth/oidc/callback`) |
|
||||
| `OIDC_SCOPES` | `openid profile email` | Scopes to request |
|
||||
| `OIDC_USERNAME_CLAIM` | `preferred_username` | Claim for username |
|
||||
| `OIDC_AUTO_CREATE_USERS` | `true` | Auto-create users on first SSO login |
|
||||
|
||||
Generated
+6
@@ -2243,6 +2243,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.10.0.tgz",
|
||||
"integrity": "sha512-2ERn08T4XOVx34yBtUPq0RDjAdd9TJ5qNH/izugr208ml2F94mk92qC64kXyDVQINodWJvp3kAdq6P4zTtCZ7g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@libsql/core": "^0.10.0",
|
||||
"@libsql/hrana-client": "^0.6.2",
|
||||
@@ -4742,6 +4743,7 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
@@ -5938,6 +5940,7 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -6699,6 +6702,7 @@
|
||||
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "~0.27.0",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
@@ -6762,6 +6766,7 @@
|
||||
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -6837,6 +6842,7 @@
|
||||
"integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vitest/expect": "4.0.16",
|
||||
"@vitest/mocker": "4.0.16",
|
||||
|
||||
@@ -144,17 +144,17 @@ export async function oidcRoutes(app: FastifyInstance) {
|
||||
|
||||
try {
|
||||
const config = await getOIDCConfig();
|
||||
const _redirectUri = env.OIDC_REDIRECT_URI!;
|
||||
const redirectUri = env.OIDC_REDIRECT_URI!;
|
||||
|
||||
// Exchange code for tokens
|
||||
const tokens = await client.authorizationCodeGrant(
|
||||
config,
|
||||
new URL(request.url, `http://${request.headers.host}`),
|
||||
{
|
||||
pkceCodeVerifier: storedVerifier.value,
|
||||
expectedState: state,
|
||||
}
|
||||
);
|
||||
// Build complete callback URL with query parameters for validation
|
||||
const callbackUrl = new URL(redirectUri);
|
||||
callbackUrl.search = new URLSearchParams(request.query as Record<string, string>).toString();
|
||||
|
||||
const tokens = await client.authorizationCodeGrant(config, callbackUrl, {
|
||||
pkceCodeVerifier: storedVerifier.value,
|
||||
expectedState: state,
|
||||
});
|
||||
|
||||
// Get user info
|
||||
const sub = tokens.claims()?.sub;
|
||||
|
||||
Reference in New Issue
Block a user