passport-i4trust
Version:
Passport strategy for authentication with FIWARE Keyrock using iShare JWT
137 lines (111 loc) • 3.7 kB
JavaScript
const base64url = require('base64url');
const OAuth2Strategy = require('passport-oauth2').OAuth2Strategy;
const jwt = require('jsonwebtoken')
const url = require('url');
const { URLSearchParams } = require('url');
const moment = require('moment');
const uuid = require('uuid');
const fs = require('fs');
function buildAuthorizationToken(options, params) {
function getCAChain(str) {
const r = new RegExp(/-----BEGIN CERTIFICATE-----\n(\S|\n)*\n-----END CERTIFICATE-----/gm);
const matches = str.match(r);
return matches.map((crt) => {
let rawCrt = crt.replace('-----BEGIN CERTIFICATE-----\n', '');
rawCrt = rawCrt.replace('\n-----END CERTIFICATE-----', '');
return rawCrt;
});
}
// Expiration to 5 min
const iat = moment().unix();
const exp = moment().add(5, 'minutes').unix();
const tokenProfile = {
"jti": uuid.v4(), // Unique JWT ID
"iss": options.clientId, // Client-ID of Marketplace (EORI)
"sub": options.clientId, // Client-ID of Marketplace (EORI)
"aud": options.idpId, // ID (EORI) of client IDP,
"iat": iat,
"nbf": iat,
"exp": exp,
"response_type": params.response_type,
"scope": params.scope,
"redirect_uri": params.redirect_uri,
"state": params.state,
"nonce": params.state, // FIXME
"acr_values": "urn:http://eidas.europa.eu/LoA/NotNotified/high"
}
// Load token key
const key = fs.readFileSync(options.tokenKey);
let secret;
if (!!options.passphrase) {
secret = {
key: key,
passphrase: options.passphrase
}
} else {
secret = key;
}
// ONLY CODE between Begin and end certificate to be provided
const cert = Buffer.from(fs.readFileSync(options.tokenCrt)).toString();
const caChain = getCAChain(cert);
console.log(caChain);
return jwt.sign(tokenProfile, secret, {
algorithm: 'RS256',
header: {
x5c: caChain
}
});
}
function makeAuthorizeRequest(self, req, options, params) {
// Build IShare token
params.request = buildAuthorizationToken(options, params);
console.log(params.request);
return;
const reqParams = new URLSearchParams(params);
// Make POST request
fetch(options.authorizeUrl, {
method: 'POST',
body: reqParams
}).then(res => {
// Get Location URI and redirect
console.log(res.status);
console.log(res.headers.get('location'));
}).catch(err => {
console.log(err);
});
}
function authorizeRequest(self, req, options) {
let params = {};
params.response_type = 'code';
params.client_id = options.clientId;
// Build redirect URI
let callbackURL = options.callbackURL;
if (callbackURL) {
params.redirect_uri = callbackURL;
}
// Build scope
let scope = options.scope;
if (scope) {
if (Array.isArray(scope)) {
scope = scope.join(',');
}
params.scope = scope;
}
// Process state
let state = options.state;
params.state = state;
makeAuthorizeRequest(self, req, options, params);
}
const authOptions = {
clientId: 'EU.EORI.NLMARKETPLA',
callbackURL: 'https://market.i4trust.com/i4trust/callback',
scope: 'jwt,openid,i4trust',
state: '12345',
idpId: 'EU.EORI.NLPACKETDEL',
tokenUrl: 'https://idp.market.i4trust.com/oauth2/token',
authorizationURL: 'http://localhost:3000/oauth2/authorize',
tokenKey: './mplace.key',
tokenCrt: './mplace.crt'
//passphrase: ''
}
authorizeRequest(this, {}, authOptions);