verify using iss attribute
This commit is contained in:
parent
b48a7cd4f2
commit
8b0969792a
@ -1,9 +1,11 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
|
import axios from "axios";
|
||||||
import { logger } from "../../utils/index.js";
|
import { logger } from "../../utils/index.js";
|
||||||
import { decode } from "jsonwebtoken";
|
import { decode } from "jsonwebtoken";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import base64url from "base64url";
|
import base64url from "base64url";
|
||||||
import jwkToPem from "jwk-to-pem";
|
import jwkToPem from "jwk-to-pem";
|
||||||
|
import { sendHTTPError } from "../../utils/http.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@ -17,44 +19,57 @@ router.post("/", (req, res) => {
|
|||||||
logger.debug(JSON.stringify(req.body, null, 2));
|
logger.debug(JSON.stringify(req.body, null, 2));
|
||||||
var authHeader = req.headers.authorization;
|
var authHeader = req.headers.authorization;
|
||||||
const prefix = "OIDC_id_token ";
|
const prefix = "OIDC_id_token ";
|
||||||
if (authHeader.startsWith(prefix)) {
|
if (authHeader && authHeader.startsWith(prefix)) {
|
||||||
var token = authHeader.substring(prefix.length, authHeader.length);
|
var token = authHeader.substring(prefix.length, authHeader.length);
|
||||||
|
|
||||||
// base64 should be URL encoded and padding should be removed.
|
// base64 should be URL encoded and padding should be removed.
|
||||||
token = base64url.fromBase64(token.replace(/=/g, ""));
|
token = base64url.fromBase64(token.replace(/=/g, ""));
|
||||||
|
|
||||||
const jwk = {
|
|
||||||
alg: "RS256",
|
|
||||||
e: "AQAB",
|
|
||||||
kid: "3818ed312ed8da55defd3a3fb48f56431ac1c02a3f6d2ad25c409fa0905457e9",
|
|
||||||
kty: "RSA",
|
|
||||||
n: "AKHh-mvG1TFYBn0nxSFPtU0PEG7fd27MGRWG92nP_FSXyLyMyIeUxKUWg5t1-2wK2ue8Z3lq8G9YqnoHfTmnKDT_zLESlKlAgx9KNeumedEQu18KyoGXK9eqnwNkV05sWGqMN4OXzp3s88o07ni2KDXiEv4UTBJP44VPDQlrophYNxA0H_BpedXUqd8J0hSheDwL_b_lktZDZB2UrgspadGPAsLLM7DRajmzB8sGXe0TZSD0jB2YnJAJZrNKzAbDeRPY4kHwt23_uM3Sa-cQe_mfQY1jkBJkz6ullCU-8twD3p3Ckdeq1g5duCD0vqPPXn5OCP8DsRpziOQSlv9p7c0=",
|
|
||||||
use: "sig",
|
|
||||||
};
|
|
||||||
|
|
||||||
var pem = jwkToPem(jwk);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const verified = jwt.verify(token, pem, { algorithms: ["RS256"] });
|
|
||||||
logger.debug(`Verified [${JSON.stringify(verified, null, 2)}]`);
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(
|
|
||||||
`verify failed [${JSON.stringify(
|
|
||||||
err,
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)}]. This is most likely because we modified the token to be URL Base64 compatible during processing`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const decoded = decode(token);
|
const decoded = decode(token);
|
||||||
logger.debug(`Decoded [${JSON.stringify(decoded, null, 2)}]`);
|
logger.debug(`Decoded [${JSON.stringify(decoded, null, 2)}]`);
|
||||||
res.send(decoded);
|
|
||||||
return;
|
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)}]`);
|
||||||
|
res.send(decoded);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(`Verify failed [${JSON.stringify(err, null, 2)}].`);
|
||||||
|
sendHTTPError(err, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
logger.error(`JWK Request failed [${JSON.stringify(err, null, 2)}].`);
|
||||||
|
sendHTTPError(err, res);
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//Error
|
sendHTTPError(
|
||||||
|
new Error("No OIDC_id_token found in Authentication header.")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
res.send({});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
13
src/utils/http.js
Normal file
13
src/utils/http.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export function sendHTTPError(err, res) {
|
||||||
|
let errStatus = 500;
|
||||||
|
if (err.response && err.response.status) errStatus = err.response.status;
|
||||||
|
res.status(errStatus).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
status: errStatus,
|
||||||
|
title: err.code,
|
||||||
|
detail: err.message,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user