mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
OIDC logout: use a fixed post logout redirect uri (#1276)
Co-authored-by: Jonathan Perret <j-github@jonathanperret.net>
This commit is contained in:
parent
c27f832851
commit
c783a4f75e
3
.gitignore
vendored
3
.gitignore
vendored
@ -94,3 +94,6 @@ xunit.xml
|
|||||||
/docker-compose-examples/*/persist
|
/docker-compose-examples/*/persist
|
||||||
/docker-compose-examples/*/secrets
|
/docker-compose-examples/*/secrets
|
||||||
/docker-compose-examples/grist-traefik-oidc-auth/.env
|
/docker-compose-examples/grist-traefik-oidc-auth/.env
|
||||||
|
|
||||||
|
# Sample grist documents
|
||||||
|
/samples/
|
||||||
|
@ -79,6 +79,7 @@ import { SendAppPageFunction } from 'app/server/lib/sendAppPage';
|
|||||||
import { StringUnionError } from 'app/common/StringUnion';
|
import { StringUnionError } from 'app/common/StringUnion';
|
||||||
import { EnabledProtection, EnabledProtectionString, ProtectionsManager } from './oidc/Protections';
|
import { EnabledProtection, EnabledProtectionString, ProtectionsManager } from './oidc/Protections';
|
||||||
import { SessionObj } from './BrowserSession';
|
import { SessionObj } from './BrowserSession';
|
||||||
|
import { getOriginUrl } from './requestUtils';
|
||||||
|
|
||||||
const CALLBACK_URL = '/oauth2/callback';
|
const CALLBACK_URL = '/oauth2/callback';
|
||||||
|
|
||||||
@ -278,18 +279,21 @@ export class OIDCConfig {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getLogoutRedirectUrl(req: express.Request, redirectUrl: URL): Promise<string> {
|
public async getLogoutRedirectUrl(req: express.Request): Promise<string> {
|
||||||
const session: SessionObj|undefined = (req as RequestWithLogin).session;
|
const session: SessionObj|undefined = (req as RequestWithLogin).session;
|
||||||
|
const stableRedirectUri = new URL('/signed-out', getOriginUrl(req)).href;
|
||||||
// For IdPs that don't have end_session_endpoint, we just redirect to the logout page.
|
// For IdPs that don't have end_session_endpoint, we just redirect to the logout page.
|
||||||
if (this._skipEndSessionEndpoint) {
|
if (this._skipEndSessionEndpoint) {
|
||||||
return redirectUrl.href;
|
// Ignore redirectUrl because OIDC providers don't allow variable redirect URIs
|
||||||
|
return stableRedirectUri;
|
||||||
}
|
}
|
||||||
// Alternatively, we could use a logout URL specified by configuration.
|
// Alternatively, we could use a logout URL specified by configuration.
|
||||||
if (this._endSessionEndpoint) {
|
if (this._endSessionEndpoint) {
|
||||||
return this._endSessionEndpoint;
|
return this._endSessionEndpoint;
|
||||||
}
|
}
|
||||||
return this._client.endSessionUrl({
|
return this._client.endSessionUrl({
|
||||||
post_logout_redirect_uri: redirectUrl.href,
|
// Ignore redirectUrl because OIDC providers don't allow variable redirect URIs
|
||||||
|
post_logout_redirect_uri: stableRedirectUri,
|
||||||
id_token_hint: session?.oidc?.idToken,
|
id_token_hint: session?.oidc?.idToken,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ describe('OIDCConfig', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getLogoutRedirectUrl', () => {
|
describe('getLogoutRedirectUrl', () => {
|
||||||
const REDIRECT_URL = new URL('http://localhost:8484/docs/signed-out');
|
const STABLE_LOGOUT_URL = new URL('http://localhost:8484/signed-out');
|
||||||
const URL_RETURNED_BY_CLIENT = 'http://localhost:8484/logout_url_from_issuer';
|
const URL_RETURNED_BY_CLIENT = 'http://localhost:8484/logout_url_from_issuer';
|
||||||
const ENV_VALUE_GRIST_OIDC_IDP_END_SESSION_ENDPOINT = 'http://localhost:8484/logout';
|
const ENV_VALUE_GRIST_OIDC_IDP_END_SESSION_ENDPOINT = 'http://localhost:8484/logout';
|
||||||
const FAKE_SESSION = {
|
const FAKE_SESSION = {
|
||||||
@ -767,7 +767,7 @@ describe('OIDCConfig', () => {
|
|||||||
env: {
|
env: {
|
||||||
GRIST_OIDC_IDP_SKIP_END_SESSION_ENDPOINT: 'true',
|
GRIST_OIDC_IDP_SKIP_END_SESSION_ENDPOINT: 'true',
|
||||||
},
|
},
|
||||||
expectedUrl: REDIRECT_URL.href,
|
expectedUrl: STABLE_LOGOUT_URL.href,
|
||||||
}, {
|
}, {
|
||||||
itMsg: 'should use the GRIST_OIDC_IDP_END_SESSION_ENDPOINT when it is set',
|
itMsg: 'should use the GRIST_OIDC_IDP_END_SESSION_ENDPOINT when it is set',
|
||||||
env: {
|
env: {
|
||||||
@ -778,14 +778,14 @@ describe('OIDCConfig', () => {
|
|||||||
itMsg: 'should call the end session endpoint with the expected parameters',
|
itMsg: 'should call the end session endpoint with the expected parameters',
|
||||||
expectedUrl: URL_RETURNED_BY_CLIENT,
|
expectedUrl: URL_RETURNED_BY_CLIENT,
|
||||||
expectedLogoutParams: {
|
expectedLogoutParams: {
|
||||||
post_logout_redirect_uri: REDIRECT_URL.href,
|
post_logout_redirect_uri: STABLE_LOGOUT_URL.href,
|
||||||
id_token_hint: FAKE_SESSION.oidc!.idToken,
|
id_token_hint: FAKE_SESSION.oidc!.idToken,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
itMsg: 'should call the end session endpoint with no idToken if session is missing',
|
itMsg: 'should call the end session endpoint with no idToken if session is missing',
|
||||||
expectedUrl: URL_RETURNED_BY_CLIENT,
|
expectedUrl: URL_RETURNED_BY_CLIENT,
|
||||||
expectedLogoutParams: {
|
expectedLogoutParams: {
|
||||||
post_logout_redirect_uri: REDIRECT_URL.href,
|
post_logout_redirect_uri: STABLE_LOGOUT_URL.href,
|
||||||
id_token_hint: undefined,
|
id_token_hint: undefined,
|
||||||
},
|
},
|
||||||
session: null
|
session: null
|
||||||
@ -798,9 +798,12 @@ describe('OIDCConfig', () => {
|
|||||||
clientStub.endSessionUrl.returns(URL_RETURNED_BY_CLIENT);
|
clientStub.endSessionUrl.returns(URL_RETURNED_BY_CLIENT);
|
||||||
const config = await OIDCConfigStubbed.buildWithStub(clientStub.asClient());
|
const config = await OIDCConfigStubbed.buildWithStub(clientStub.asClient());
|
||||||
const req = {
|
const req = {
|
||||||
|
headers: {
|
||||||
|
host: STABLE_LOGOUT_URL.host
|
||||||
|
},
|
||||||
session: 'session' in ctx ? ctx.session : FAKE_SESSION
|
session: 'session' in ctx ? ctx.session : FAKE_SESSION
|
||||||
} as unknown as RequestWithLogin;
|
} as unknown as RequestWithLogin;
|
||||||
const url = await config.getLogoutRedirectUrl(req, REDIRECT_URL);
|
const url = await config.getLogoutRedirectUrl(req);
|
||||||
assert.equal(url, ctx.expectedUrl);
|
assert.equal(url, ctx.expectedUrl);
|
||||||
if (ctx.expectedLogoutParams) {
|
if (ctx.expectedLogoutParams) {
|
||||||
assert.isTrue(clientStub.endSessionUrl.calledOnce);
|
assert.isTrue(clientStub.endSessionUrl.calledOnce);
|
||||||
|
Loading…
Reference in New Issue
Block a user