From 8c96305b2c179b2f26b9b625621c725f7364f946 Mon Sep 17 00:00:00 2001 From: Dominik Hebeler <dominik@hebeler.club> Date: Sun, 1 Jan 2023 21:42:12 +0100 Subject: [PATCH] finished oidc connect integration with keycloak --- pass/routes/authentication.js | 80 ++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/pass/routes/authentication.js b/pass/routes/authentication.js index e905945..7b24307 100644 --- a/pass/routes/authentication.js +++ b/pass/routes/authentication.js @@ -2,72 +2,74 @@ var express = require("express"); var router = express.Router(); const config = require("config"); const jose = require("jose"); -const { auth, requiresAuth, Session } = require("express-openid-connect"); -const dayjs = require("dayjs"); +const { auth, requiresAuth, claimCheck } = require("express-openid-connect"); -const auth_session_expiration_minutes = 1; - -const access_keys_redis_key = "accesskeys"; +const auth_session_expiration_seconds = 60; /** - * Authorization is done using Oauth2 via any GitLab Instance + * Authorization is done using Oauth2 via any Openid Provider * The Instance to be used can be configured in the config. * - * The authenticated user needs to be member of the group defined in the config - * * You can call any url with the parameter moderation=true to trigger a login with * redirect to the same URL after successfull authentication or 401 error on * failed authentication. - * - * Create an application in your Gitlab Instances Group with openid,profile,email permissions - * and set the callback URL to this applications base url and the path /callback - * */ router.use( + // General Optional authorization for every page + // It will not require login or start a session by default + // Only when a route uses the middleware requireAuth auth({ issuerBaseURL: `${config.get("app.openid_auth.url")}`, baseURL: config.get("app.url"), clientID: config.get("app.openid_auth.app_id"), clientSecret: config.get("app.openid_auth.app_secret"), secret: config.get("app.secret"), - idpLogout: true, session: { - absoluteDuration: 1, - }, - afterCallback: (req, res, session, decodedState) => { - let access_token = session.access_token; - console.log(session); - return session; + rollingDuration: auth_session_expiration_seconds, + signSessionStoreCookie: true, }, authRequired: false, - authorizationParams: { - response_type: "code", - }, }), + /** + * If the user is already authenticated this middleware will check + * if the user inherits the required role in his oidc token to use this app + */ (req, res, next) => { - if (req.query.moderation) { - requiresAuth()(req, res, next); + if (req.data === undefined) { + req.data = { admin: false }; } else { - next("route"); + req.data.admin = false; + } + if (req.oidc.isAuthenticated()) { + claimCheck((req, claims) => { + if (req.oidc.isAuthenticated()) { + if ( + claims.resource_access !== undefined && + claims.resource_access["metager-key"] !== undefined && + claims.resource_access["metager-key"].roles !== undefined && + claims.resource_access["metager-key"].roles.includes("metager-key") + ) { + req.data.admin = true; + } + return true; + } + })(req, res, next); + } else { + next(); } }, + // Require authorization for every route with moderation request parameter set + // Or when the user already is authenticated (req, res, next) => { - if (req.data) { - req.data.admin = false; + if (req.query.moderation || req.data.admin) { + requiresAuth()(req, res, next); } else { - req.data = { - admin: false, - }; - } - if (Object.keys(req.appSession).length > 0) { - let claims = jose.decodeJwt(req.appSession.id_token); - if ( - claims.groups_direct.includes(config.get("app.gitlab.required_group")) - ) { - req.data.admin = true; - } + next("route"); } - + }, + // Redirect the user to the same URL without moderation URL Parameter after + // successful auth. Show him a 401 if he does not inherit required role + (req, res, next) => { if (req.query.moderation) { if (!req.data.admin) { res.locals.error = { status: 401 }; -- GitLab