113 lines
3.5 KiB
JavaScript
113 lines
3.5 KiB
JavaScript
import { Router } from "express";
|
|
import axios from "axios";
|
|
import { logger, store } from "../../utils/index.js";
|
|
import { decode } from "jsonwebtoken";
|
|
import jwt from "jsonwebtoken";
|
|
import jwkToPem from "jwk-to-pem";
|
|
|
|
const router = Router();
|
|
|
|
router.all("/", (req, res, next) => {
|
|
var token = null;
|
|
var sessionIdentifier = null;
|
|
const cookiePrefix = "__Host-VRNTOTCT";
|
|
|
|
if (req.cookies) {
|
|
logger.debug(
|
|
`Checking ${cookiePrefix}... Cookie as this takes presidence over Authorization Header ...`
|
|
);
|
|
Object.keys(req.cookies).forEach((key) => {
|
|
if (key.startsWith(cookiePrefix)) {
|
|
logger.info(`Found ${key} cookie using value for token`);
|
|
token = req.cookies[key];
|
|
sessionIdentifier = key.substring(cookiePrefix.length);
|
|
}
|
|
});
|
|
}
|
|
if (!token && req.headers.authorization) {
|
|
logger.debug("Checking Authorization Header for OIDC_id_token ...");
|
|
var authHeader = req.headers.authorization;
|
|
const prefix = "OIDC_id_token ";
|
|
if (authHeader && authHeader.startsWith(prefix)) {
|
|
logger.info("Found OIDC_id_token in Authorization Header");
|
|
token = authHeader.substring(prefix.length, authHeader.length);
|
|
}
|
|
}
|
|
|
|
if (token) {
|
|
const decoded = decode(token);
|
|
logger.debug(`Decoded [${JSON.stringify(decoded, null, 2)}]`);
|
|
|
|
if (decoded.iss) {
|
|
const jwkURI = decoded.iss + "/connect/jwk_uri";
|
|
|
|
logger.debug(`Requesting JWK on ${jwkURI}`);
|
|
|
|
axios
|
|
.get(jwkURI)
|
|
.then((jwkResponse) => {
|
|
logger.debug(
|
|
`Response JWK on ${JSON.stringify(jwkResponse.data, null, 2)}`
|
|
);
|
|
|
|
if (
|
|
jwkResponse.data &&
|
|
jwkResponse.data.keys &&
|
|
jwkResponse.data.keys.length > 0
|
|
) {
|
|
const key = jwkResponse.data.keys[0];
|
|
var pem = jwkToPem(key);
|
|
|
|
try {
|
|
const verified = jwt.verify(token, pem, {
|
|
algorithms: [key.alg],
|
|
});
|
|
logger.debug(`Verified [${JSON.stringify(verified, null, 2)}]`);
|
|
|
|
const issSplit = verified.iss.split("/oidc-token-service/");
|
|
|
|
const authData = {
|
|
token: token,
|
|
host: issSplit[0],
|
|
tenant: issSplit[1],
|
|
};
|
|
|
|
const authDataString = JSON.stringify(authData);
|
|
|
|
logger.info(
|
|
`Adding agent ${verified.sub} to store for environment ${authDataString}}`
|
|
);
|
|
store
|
|
.set(verified.sub, authData)
|
|
.then(() => {
|
|
if (sessionIdentifier && sessionIdentifier.length > 0) {
|
|
logger.info(
|
|
`Adding sessionIdentifier ${sessionIdentifier} to store for environment ${authDataString}`
|
|
);
|
|
return store.set(sessionIdentifier, authData);
|
|
}
|
|
})
|
|
.then(() => {
|
|
res.send(decoded);
|
|
})
|
|
.catch((e) => {
|
|
logger.error(e); // "Uh-oh!"
|
|
});
|
|
} catch (err) {
|
|
logger.error(`Verify failed [${JSON.stringify(err, null, 2)}].`);
|
|
next(err);
|
|
}
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
logger.error(`JWK Request failed [${JSON.stringify(err, null, 2)}].`);
|
|
next(err);
|
|
});
|
|
}
|
|
} else {
|
|
next(new Error("Unable to authenticate, no token found"));
|
|
}
|
|
});
|
|
|
|
export default router;
|