feat: preserve RFC 8707 resource across browser login flow (#5298)

This commit is contained in:
Modo
2026-03-22 09:30:59 +08:00
committed by GitHub
parent 65755d3b28
commit 29dccbe32f
4 changed files with 19 additions and 4 deletions

View File

@@ -159,6 +159,7 @@
codeChallenge: getRefinedValue(innerParams.get("code_challenge")),
responseMode: getRefinedValue(innerParams.get("response_mode")),
relayState: getRefinedValue(lowercaseQueries["relaystate"]),
resource: getRefinedValue(innerParams.get("resource")),
type: "code"
};
}
@@ -168,6 +169,10 @@
return "";
}
var resourceQuery = oAuthParams.resource
? "&resource=" + encodeURIComponent(oAuthParams.resource)
: "";
return "?clientId=" + oAuthParams.clientId +
"&responseType=" + oAuthParams.responseType +
"&redirectUri=" + encodeURIComponent(oAuthParams.redirectUri) +
@@ -176,7 +181,8 @@
"&state=" + oAuthParams.state +
"&nonce=" + oAuthParams.nonce +
"&code_challenge_method=" + oAuthParams.challengeMethod +
"&code_challenge=" + oAuthParams.codeChallenge;
"&code_challenge=" + oAuthParams.codeChallenge +
resourceQuery;
}
function createFormAndSubmit(action, params) {
@@ -424,4 +430,4 @@
});
}
};
})();
})();

View File

@@ -56,8 +56,12 @@ export function oAuthParamsToQuery(oAuthParams) {
return "";
}
const resourceQuery = oAuthParams.resource
? `&resource=${encodeURIComponent(oAuthParams.resource)}`
: "";
// code
return `?clientId=${oAuthParams.clientId}&responseType=${oAuthParams.responseType}&redirectUri=${encodeURIComponent(oAuthParams.redirectUri)}&type=${oAuthParams.type}&scope=${oAuthParams.scope}&state=${oAuthParams.state}&nonce=${oAuthParams.nonce}&code_challenge_method=${oAuthParams.challengeMethod}&code_challenge=${oAuthParams.codeChallenge}`;
return `?clientId=${oAuthParams.clientId}&responseType=${oAuthParams.responseType}&redirectUri=${encodeURIComponent(oAuthParams.redirectUri)}&type=${oAuthParams.type}&scope=${oAuthParams.scope}&state=${oAuthParams.state}&nonce=${oAuthParams.nonce}&code_challenge_method=${oAuthParams.challengeMethod}&code_challenge=${oAuthParams.codeChallenge}${resourceQuery}`;
}
export function getApplicationLogin(params) {

View File

@@ -1272,9 +1272,12 @@ class LoginPage extends React.Component {
const rawId = assertion.rawId;
const sig = assertion.response.signature;
const userHandle = assertion.response.userHandle;
const resourceQuery = oAuthParams?.resource
? `&resource=${encodeURIComponent(oAuthParams.resource)}`
: "";
let finishUrl = `${Setting.ServerUrl}/api/webauthn/signin/finish?responseType=${values["type"]}`;
if (values["type"] === "code") {
finishUrl = `${Setting.ServerUrl}/api/webauthn/signin/finish?responseType=${values["type"]}&clientId=${oAuthParams.clientId}&scope=${oAuthParams.scope}&redirectUri=${oAuthParams.redirectUri}&nonce=${oAuthParams.nonce}&state=${oAuthParams.state}&codeChallenge=${oAuthParams.codeChallenge}&challengeMethod=${oAuthParams.challengeMethod}`;
finishUrl = `${Setting.ServerUrl}/api/webauthn/signin/finish?responseType=${values["type"]}&clientId=${oAuthParams.clientId}&scope=${oAuthParams.scope}&redirectUri=${oAuthParams.redirectUri}&nonce=${oAuthParams.nonce}&state=${oAuthParams.state}&codeChallenge=${oAuthParams.codeChallenge}&challengeMethod=${oAuthParams.challengeMethod}${resourceQuery}`;
}
return fetch(finishUrl, {
method: "POST",

View File

@@ -141,6 +141,7 @@ export function getOAuthGetParameters(params) {
const samlRequest = getRefinedValue(lowercaseQueries["samlRequest".toLowerCase()]);
const relayState = getRefinedValue(lowercaseQueries["RelayState".toLowerCase()]);
const noRedirect = getRefinedValue(lowercaseQueries["noRedirect".toLowerCase()]);
const resource = getRefinedValue(queries.get("resource"));
if (clientId === "" && samlRequest === "") {
// login
@@ -160,6 +161,7 @@ export function getOAuthGetParameters(params) {
samlRequest: samlRequest,
relayState: relayState,
noRedirect: noRedirect,
resource: resource,
type: "code",
};
}