mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 18:00:15 +01:00
🛠️ fix: Workaround for Federated OpenID Nonce Validation Issues (#9067)
* fix: generate nonce for federated providers * fix: lint issues * chore: comments --------- Co-authored-by: Danny Avila <danacordially@gmail.com>
This commit is contained in:
parent
cebf140bce
commit
a6d7ebf22e
1 changed files with 26 additions and 0 deletions
|
|
@ -99,6 +99,7 @@ class CustomOpenIDStrategy extends OpenIDStrategy {
|
||||||
const hostAndProtocol = process.env.DOMAIN_SERVER;
|
const hostAndProtocol = process.env.DOMAIN_SERVER;
|
||||||
return new URL(`${hostAndProtocol}${req.originalUrl ?? req.url}`);
|
return new URL(`${hostAndProtocol}${req.originalUrl ?? req.url}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
authorizationRequestParams(req, options) {
|
authorizationRequestParams(req, options) {
|
||||||
const params = super.authorizationRequestParams(req, options);
|
const params = super.authorizationRequestParams(req, options);
|
||||||
if (options?.state && !params.has('state')) {
|
if (options?.state && !params.has('state')) {
|
||||||
|
|
@ -112,6 +113,15 @@ class CustomOpenIDStrategy extends OpenIDStrategy {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generate nonce for federated providers that require it */
|
||||||
|
const shouldGenerateNonce = isEnabled(process.env.OPENID_GENERATE_NONCE);
|
||||||
|
if (shouldGenerateNonce && !params.has('nonce') && this._sessionKey) {
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const nonce = crypto.randomBytes(16).toString('hex');
|
||||||
|
params.set('nonce', nonce);
|
||||||
|
logger.debug('[openidStrategy] Generated nonce for federated provider:', nonce);
|
||||||
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -276,12 +286,20 @@ function convertToUsername(input, defaultValue = '') {
|
||||||
*/
|
*/
|
||||||
async function setupOpenId() {
|
async function setupOpenId() {
|
||||||
try {
|
try {
|
||||||
|
const shouldGenerateNonce = isEnabled(process.env.OPENID_GENERATE_NONCE);
|
||||||
|
|
||||||
/** @type {ClientMetadata} */
|
/** @type {ClientMetadata} */
|
||||||
const clientMetadata = {
|
const clientMetadata = {
|
||||||
client_id: process.env.OPENID_CLIENT_ID,
|
client_id: process.env.OPENID_CLIENT_ID,
|
||||||
client_secret: process.env.OPENID_CLIENT_SECRET,
|
client_secret: process.env.OPENID_CLIENT_SECRET,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (shouldGenerateNonce) {
|
||||||
|
clientMetadata.response_types = ['code'];
|
||||||
|
clientMetadata.grant_types = ['authorization_code'];
|
||||||
|
clientMetadata.token_endpoint_auth_method = 'client_secret_post';
|
||||||
|
}
|
||||||
|
|
||||||
/** @type {Configuration} */
|
/** @type {Configuration} */
|
||||||
openidConfig = await client.discovery(
|
openidConfig = await client.discovery(
|
||||||
new URL(process.env.OPENID_ISSUER),
|
new URL(process.env.OPENID_ISSUER),
|
||||||
|
|
@ -297,11 +315,19 @@ async function setupOpenId() {
|
||||||
const requiredRoleParameterPath = process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH;
|
const requiredRoleParameterPath = process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH;
|
||||||
const requiredRoleTokenKind = process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND;
|
const requiredRoleTokenKind = process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND;
|
||||||
const usePKCE = isEnabled(process.env.OPENID_USE_PKCE);
|
const usePKCE = isEnabled(process.env.OPENID_USE_PKCE);
|
||||||
|
logger.info(`[openidStrategy] OpenID authentication configuration`, {
|
||||||
|
generateNonce: shouldGenerateNonce,
|
||||||
|
reason: shouldGenerateNonce
|
||||||
|
? 'OPENID_GENERATE_NONCE=true - Will generate nonce and use explicit metadata for federated providers'
|
||||||
|
: 'OPENID_GENERATE_NONCE=false - Standard flow without explicit nonce or metadata',
|
||||||
|
});
|
||||||
|
|
||||||
const openidLogin = new CustomOpenIDStrategy(
|
const openidLogin = new CustomOpenIDStrategy(
|
||||||
{
|
{
|
||||||
config: openidConfig,
|
config: openidConfig,
|
||||||
scope: process.env.OPENID_SCOPE,
|
scope: process.env.OPENID_SCOPE,
|
||||||
callbackURL: process.env.DOMAIN_SERVER + process.env.OPENID_CALLBACK_URL,
|
callbackURL: process.env.DOMAIN_SERVER + process.env.OPENID_CALLBACK_URL,
|
||||||
|
clockTolerance: process.env.OPENID_CLOCK_TOLERANCE || 300,
|
||||||
usePKCE,
|
usePKCE,
|
||||||
},
|
},
|
||||||
async (tokenset, done) => {
|
async (tokenset, done) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue