mirror of
https://github.com/plankanban/planka.git
synced 2025-07-19 13:19:44 +02:00
feat: Improve OIDC support for strict providers (#824)
This commit is contained in:
parent
042ab0a63a
commit
d45cbeb0fb
5 changed files with 34 additions and 6 deletions
|
@ -13,6 +13,9 @@ const Errors = {
|
||||||
MISSING_VALUES: {
|
MISSING_VALUES: {
|
||||||
missingValues: 'Unable to retrieve required values (email, name)',
|
missingValues: 'Unable to retrieve required values (email, name)',
|
||||||
},
|
},
|
||||||
|
INVALID_USERINFO_SIGNATURE: {
|
||||||
|
invalidUserInfoSignature: "Invalid signature on userInfo due to client misconfiguration"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -40,6 +43,9 @@ module.exports = {
|
||||||
missingValues: {
|
missingValues: {
|
||||||
responseType: 'unprocessableEntity',
|
responseType: 'unprocessableEntity',
|
||||||
},
|
},
|
||||||
|
invalidUserInfoSignature: {
|
||||||
|
responseType: 'unauthorized',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
async fn(inputs) {
|
async fn(inputs) {
|
||||||
|
@ -51,6 +57,7 @@ module.exports = {
|
||||||
sails.log.warn(`Invalid code or nonce! (IP: ${remoteAddress})`);
|
sails.log.warn(`Invalid code or nonce! (IP: ${remoteAddress})`);
|
||||||
return Errors.INVALID_CODE_OR_NONCE;
|
return Errors.INVALID_CODE_OR_NONCE;
|
||||||
})
|
})
|
||||||
|
.intercept('invalidUserInfoSignature', () => Errors.INVALID_USERINFO_SIGNATURE)
|
||||||
.intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE)
|
.intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE)
|
||||||
.intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE)
|
.intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE)
|
||||||
.intercept('missingValues', () => Errors.MISSING_VALUES);
|
.intercept('missingValues', () => Errors.MISSING_VALUES);
|
||||||
|
|
|
@ -4,11 +4,16 @@ module.exports = {
|
||||||
if (sails.hooks.oidc.isActive()) {
|
if (sails.hooks.oidc.isActive()) {
|
||||||
const oidcClient = sails.hooks.oidc.getClient();
|
const oidcClient = sails.hooks.oidc.getClient();
|
||||||
|
|
||||||
oidc = {
|
const authorizationParameters = {
|
||||||
authorizationUrl: oidcClient.authorizationUrl({
|
|
||||||
scope: sails.config.custom.oidcScopes,
|
scope: sails.config.custom.oidcScopes,
|
||||||
response_mode: 'fragment',
|
}
|
||||||
}),
|
|
||||||
|
if(!sails.config.custom.oidcDefaultResponseMode) {
|
||||||
|
authorizationParameters.response_mode = sails.config.custom.oidcResponseMode
|
||||||
|
}
|
||||||
|
|
||||||
|
oidc = {
|
||||||
|
authorizationUrl: oidcClient.authorizationUrl(authorizationParameters),
|
||||||
endSessionUrl: oidcClient.issuer.end_session_endpoint ? oidcClient.endSessionUrl({}) : null,
|
endSessionUrl: oidcClient.issuer.end_session_endpoint ? oidcClient.endSessionUrl({}) : null,
|
||||||
isEnforced: sails.config.custom.oidcEnforced,
|
isEnforced: sails.config.custom.oidcEnforced,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
exits: {
|
exits: {
|
||||||
|
invalidUserInfoSignature: {},
|
||||||
invalidCodeOrNonce: {},
|
invalidCodeOrNonce: {},
|
||||||
missingValues: {},
|
missingValues: {},
|
||||||
emailAlreadyInUse: {},
|
emailAlreadyInUse: {},
|
||||||
|
@ -34,6 +35,10 @@ module.exports = {
|
||||||
);
|
);
|
||||||
userInfo = await client.userinfo(tokenSet);
|
userInfo = await client.userinfo(tokenSet);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (e instanceof SyntaxError && e.message.includes('Unexpected token e in JSON at position 0')) {
|
||||||
|
sails.log.warn('Error while exchanging OIDC code: userInfo response is signed.');
|
||||||
|
throw 'invalidUserInfoSignature';
|
||||||
|
}
|
||||||
sails.log.warn(`Error while exchanging OIDC code: ${e}`);
|
sails.log.warn(`Error while exchanging OIDC code: ${e}`);
|
||||||
throw 'invalidCodeOrNonce';
|
throw 'invalidCodeOrNonce';
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,19 @@ module.exports = function defineOidcHook(sails) {
|
||||||
|
|
||||||
const issuer = await openidClient.Issuer.discover(sails.config.custom.oidcIssuer);
|
const issuer = await openidClient.Issuer.discover(sails.config.custom.oidcIssuer);
|
||||||
|
|
||||||
client = new issuer.Client({
|
const metadata = {
|
||||||
client_id: sails.config.custom.oidcClientId,
|
client_id: sails.config.custom.oidcClientId,
|
||||||
client_secret: sails.config.custom.oidcClientSecret,
|
client_secret: sails.config.custom.oidcClientSecret,
|
||||||
redirect_uris: [sails.config.custom.oidcRedirectUri],
|
redirect_uris: [sails.config.custom.oidcRedirectUri],
|
||||||
response_types: ['code'],
|
response_types: ['code'],
|
||||||
});
|
userinfo_signed_response_alg: sails.config.custom.oidcUserinfoSignedResponseAlg,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sails.config.custom.oidcIdTokenSignedResponseAlg) {
|
||||||
|
metadata.id_token_signed_response_alg = sails.config.custom.oidcIdTokenSignedResponseAlg
|
||||||
|
}
|
||||||
|
|
||||||
|
client = new issuer.Client(metadata);
|
||||||
},
|
},
|
||||||
|
|
||||||
getClient() {
|
getClient() {
|
||||||
|
|
|
@ -39,7 +39,11 @@ module.exports.custom = {
|
||||||
oidcIssuer: process.env.OIDC_ISSUER,
|
oidcIssuer: process.env.OIDC_ISSUER,
|
||||||
oidcClientId: process.env.OIDC_CLIENT_ID,
|
oidcClientId: process.env.OIDC_CLIENT_ID,
|
||||||
oidcClientSecret: process.env.OIDC_CLIENT_SECRET,
|
oidcClientSecret: process.env.OIDC_CLIENT_SECRET,
|
||||||
|
oidcIdTokenSignedResponseAlg: process.env.OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG,
|
||||||
|
oidcUserinfoSignedResponseAlg: process.env.OIDC_USERINFO_SIGNED_RESPONSE_ALG,
|
||||||
oidcScopes: process.env.OIDC_SCOPES || 'openid email profile',
|
oidcScopes: process.env.OIDC_SCOPES || 'openid email profile',
|
||||||
|
oidcResponseMode: process.env.OIDC_RESPONSE_MODE || 'fragment',
|
||||||
|
oidcDefaultResponseMode: process.env.OIDC_DEFAULT_RESPONSE_MODE === 'true',
|
||||||
oidcAdminRoles: process.env.OIDC_ADMIN_ROLES ? process.env.OIDC_ADMIN_ROLES.split(',') : [],
|
oidcAdminRoles: process.env.OIDC_ADMIN_ROLES ? process.env.OIDC_ADMIN_ROLES.split(',') : [],
|
||||||
oidcEmailAttribute: process.env.OIDC_EMAIL_ATTRIBUTE || 'email',
|
oidcEmailAttribute: process.env.OIDC_EMAIL_ATTRIBUTE || 'email',
|
||||||
oidcNameAttribute: process.env.OIDC_NAME_ATTRIBUTE || 'name',
|
oidcNameAttribute: process.env.OIDC_NAME_ATTRIBUTE || 'name',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue