mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-21 17:26:29 -05:00
feat(auth): add OIDC state parameter
Signed-off-by: Ivan Li <ivanli2048@gmail.com>
This commit is contained in:
parent
8b6bedab39
commit
19f4baf79b
3 changed files with 26 additions and 1 deletions
|
@ -41,12 +41,15 @@ export class OidcController {
|
||||||
@Param('oidcIdentifier') oidcIdentifier: string,
|
@Param('oidcIdentifier') oidcIdentifier: string,
|
||||||
): { url: string } {
|
): { url: string } {
|
||||||
const code = this.oidcService.generateCode();
|
const code = this.oidcService.generateCode();
|
||||||
|
const state = this.oidcService.generateState();
|
||||||
request.session.oidcLoginCode = code;
|
request.session.oidcLoginCode = code;
|
||||||
|
request.session.oidcLoginState = state;
|
||||||
request.session.authProviderType = ProviderType.OIDC;
|
request.session.authProviderType = ProviderType.OIDC;
|
||||||
request.session.authProviderIdentifier = oidcIdentifier;
|
request.session.authProviderIdentifier = oidcIdentifier;
|
||||||
const authorizationUrl = this.oidcService.getAuthorizationUrl(
|
const authorizationUrl = this.oidcService.getAuthorizationUrl(
|
||||||
oidcIdentifier,
|
oidcIdentifier,
|
||||||
code,
|
code,
|
||||||
|
state,
|
||||||
);
|
);
|
||||||
return { url: authorizationUrl };
|
return { url: authorizationUrl };
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,14 +119,28 @@ export class OidcService {
|
||||||
return generators.codeVerifier();
|
return generators.codeVerifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random state for the OIDC login.
|
||||||
|
*
|
||||||
|
* @returns {string} The generated state.
|
||||||
|
*/
|
||||||
|
generateState(): string {
|
||||||
|
return generators.state();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the authorization URL for the given OIDC identifier and code.
|
* Generates the authorization URL for the given OIDC identifier and code.
|
||||||
*
|
*
|
||||||
* @param {string} oidcIdentifier The identifier of the OIDC configuration
|
* @param {string} oidcIdentifier The identifier of the OIDC configuration
|
||||||
* @param {string} code The code verifier generated for the login
|
* @param {string} code The code verifier generated for the login
|
||||||
|
* @param {string} state The state generated for the login
|
||||||
* @returns {string} The generated authorization URL
|
* @returns {string} The generated authorization URL
|
||||||
*/
|
*/
|
||||||
getAuthorizationUrl(oidcIdentifier: string, code: string): string {
|
getAuthorizationUrl(
|
||||||
|
oidcIdentifier: string,
|
||||||
|
code: string,
|
||||||
|
state: string,
|
||||||
|
): string {
|
||||||
const clientConfig = this.clientConfigs.get(oidcIdentifier);
|
const clientConfig = this.clientConfigs.get(oidcIdentifier);
|
||||||
if (!clientConfig) {
|
if (!clientConfig) {
|
||||||
throw new NotFoundException(
|
throw new NotFoundException(
|
||||||
|
@ -139,6 +153,7 @@ export class OidcService {
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
code_challenge: generators.codeChallenge(code),
|
code_challenge: generators.codeChallenge(code),
|
||||||
code_challenge_method: 'S256',
|
code_challenge_method: 'S256',
|
||||||
|
state,
|
||||||
/* eslint-enable @typescript-eslint/naming-convention */
|
/* eslint-enable @typescript-eslint/naming-convention */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -166,15 +181,18 @@ export class OidcService {
|
||||||
const oidcConfig = clientConfig.config;
|
const oidcConfig = clientConfig.config;
|
||||||
const params = client.callbackParams(request);
|
const params = client.callbackParams(request);
|
||||||
const code = request.session.oidcLoginCode;
|
const code = request.session.oidcLoginCode;
|
||||||
|
const state = request.session.oidcLoginState;
|
||||||
const isAutodiscovered = clientConfig.config.authorizeUrl === undefined;
|
const isAutodiscovered = clientConfig.config.authorizeUrl === undefined;
|
||||||
const tokenSet = isAutodiscovered
|
const tokenSet = isAutodiscovered
|
||||||
? await client.callback(clientConfig.redirectUri, params, {
|
? await client.callback(clientConfig.redirectUri, params, {
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
code_verifier: code,
|
code_verifier: code,
|
||||||
|
state,
|
||||||
})
|
})
|
||||||
: await client.oauthCallback(clientConfig.redirectUri, params, {
|
: await client.oauthCallback(clientConfig.redirectUri, params, {
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
code_verifier: code,
|
code_verifier: code,
|
||||||
|
state,
|
||||||
});
|
});
|
||||||
|
|
||||||
request.session.oidcIdToken = tokenSet.id_token;
|
request.session.oidcIdToken = tokenSet.id_token;
|
||||||
|
@ -214,6 +232,7 @@ export class OidcService {
|
||||||
request.session.newUserData = newUserData;
|
request.session.newUserData = newUserData;
|
||||||
// Cleanup: The code isn't necessary anymore
|
// Cleanup: The code isn't necessary anymore
|
||||||
request.session.oidcLoginCode = undefined;
|
request.session.oidcLoginCode = undefined;
|
||||||
|
request.session.oidcLoginState = undefined;
|
||||||
return newUserData;
|
return newUserData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,9 @@ export interface SessionState {
|
||||||
/** The (random) OIDC code for verifying that OIDC responses match the OIDC requests */
|
/** The (random) OIDC code for verifying that OIDC responses match the OIDC requests */
|
||||||
oidcLoginCode?: string;
|
oidcLoginCode?: string;
|
||||||
|
|
||||||
|
/** The (random) OIDC state for verifying that OIDC responses match the OIDC requests */
|
||||||
|
oidcLoginState?: string;
|
||||||
|
|
||||||
/** The user id as provided from the external auth provider, required for matching to a HedgeDoc identity */
|
/** The user id as provided from the external auth provider, required for matching to a HedgeDoc identity */
|
||||||
providerUserId?: string;
|
providerUserId?: string;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue