Created
September 9, 2020 10:48
-
-
Save code-atom/791c9e161ccea98258e91b1f82a0a77d to your computer and use it in GitHub Desktop.
OIDC Authorization Proof Key in Postman Per-Request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var crypto = require("crypto-js"); | |
var interval = setTimeout(function() {}, 10000); | |
var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
var b64pad = "="; | |
var stsEndpoint = 'https://XX-XXX-XXX-XXX.XXX.net/ids'; | |
var tokenEndpoint = stsEndpoint + '/connect/token'; | |
var authorizationEndpoint = stsEndpoint + '/connect/authorize'; | |
var loginEndpoint = stsEndpoint + '/login'; | |
var redirectUrl = 'https://XXX-XX-XX-XXX.azurewebsites.net/sign-in'; | |
var clientId = 'XXXX' | |
var clientSecret = 'XXXX'; | |
var scopes = 'openid'; | |
const authorizeRequest = { | |
scope: "scope", | |
responseType: "response_type", | |
clientId: "client_id", | |
redirectUri: "redirect_uri", | |
state: "state", | |
responseMode: "response_mode", | |
nonce: "nonce", | |
display: "display", | |
prompt: "prompt", | |
maxAge: "max_age", | |
uiLocales: "ui_locales", | |
idTokenHint: "id_token_hint", | |
loginHint: "login_hint", | |
acrValues: "acr_values", | |
codeChallenge: "code_challenge", | |
codeChallengeMethod: "code_challenge_method", | |
request: "request", | |
requestUri: "request_uri" | |
}; | |
function addOptional(values, key, value) { | |
if (value) { | |
values[key] = value; | |
} | |
}; | |
function objectToQuerystring(obj) { | |
return Object.keys(obj).reduce(function (str, key, i) { | |
var delimiter, val; | |
delimiter = (i === 0) ? '?' : '&'; | |
key = encodeURIComponent(key); | |
val = encodeURIComponent(obj[key]); | |
return [str, delimiter, key, '=', val].join(''); | |
}, ''); | |
}; | |
function uuid() { | |
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => | |
(c ^ Math.random() * 16 >> c / 4).toString(16) | |
) | |
} | |
function random() { | |
return uuid().replace(/-/g, ''); | |
} | |
function hexToBase64(h) { | |
var i; | |
var c; | |
var ret = ""; | |
for (i = 0; i + 3 <= h.length; i += 3) { | |
c = parseInt(h.substring(i, i + 3), 16); | |
ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); | |
} | |
if (i + 1 === h.length) { | |
c = parseInt(h.substring(i, i + 1), 16); | |
ret += b64map.charAt(c << 2); | |
} | |
else if (i + 2 === h.length) { | |
c = parseInt(h.substring(i, i + 2), 16); | |
ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); | |
} | |
if (b64pad) while ((ret.length & 3) > 0) ret += b64pad; | |
return ret; | |
} | |
function base64ToBase64Url(s) { | |
s = s.replace(/=/g, ""); | |
s = s.replace(/\+/g, "-"); | |
s = s.replace(/\//g, "_"); | |
return s; | |
} | |
function hextob64u(s) { | |
if (s.length % 2 === 1) { | |
s = '0' + s; | |
} | |
return base64ToBase64Url(hexToBase64(s)); | |
} | |
function createAuthorizeUri( | |
requestUri, | |
clientId, | |
responseType, | |
scope, | |
redirectUri, | |
state, | |
responseMode, | |
codeChallenge, | |
codeChallengeMethod, | |
nonce, | |
loginHint, | |
acrValues, | |
prompt, | |
display, | |
maxAge, | |
uiLocales, | |
idTokenHint, | |
extra | |
) { | |
var promise = new Promise((resolve, reject) => { | |
var values = {}; | |
values[authorizeRequest.clientId] = clientId; | |
values[authorizeRequest.responseType] = responseType; | |
addOptional(values, authorizeRequest.scope, scope); | |
addOptional(values, authorizeRequest.redirectUri, redirectUri); | |
addOptional(values, authorizeRequest.state, state); | |
addOptional(values, authorizeRequest.nonce, nonce); | |
addOptional(values, authorizeRequest.loginHint, loginHint); | |
addOptional(values, authorizeRequest.acrValues, acrValues); | |
addOptional(values, authorizeRequest.prompt, prompt); | |
addOptional(values, authorizeRequest.responseMode, responseMode); | |
addOptional(values, authorizeRequest.codeChallenge, codeChallenge); | |
addOptional(values, authorizeRequest.codeChallengeMethod, codeChallengeMethod); | |
addOptional(values, authorizeRequest.display, display); | |
addOptional(values, authorizeRequest.maxAge, maxAge); | |
addOptional(values, authorizeRequest.uiLocales, uiLocales); | |
addOptional(values, authorizeRequest.idTokenHint, idTokenHint); | |
var endpoint = requestUri + objectToQuerystring(values); | |
pm.sendRequest(endpoint, function (err, response, additional) { | |
if (err) { | |
reject(err); | |
} | |
const session = additional.cookies.filter(x => x.name === 'idsrv')[0]; | |
const responseBody = cheerio.load(response.stream.toString()); | |
resolve({ body: responseBody, sessionExist: !!session }); | |
}) | |
}) | |
return promise; | |
}; | |
function createLoginRequest( | |
endpoint, | |
username, | |
password, | |
xsfrToken, | |
) { | |
var promise = new Promise((resolve, reject) => { | |
const request = { | |
url: endpoint, | |
method: 'POST', | |
header: { | |
'Accept': 'application/json', | |
'Content-Type': 'application/x-www-form-urlencoded', | |
}, | |
body: { | |
mode: 'urlencoded', | |
urlencoded: [ | |
{ key: "username", value: username, disabled: false }, | |
{ key: "password", value: password, disabled: false }, | |
{ key: "button", value: "login", disabled: false }, | |
{ key: "__RequestVerificationToken", value: xsfrToken, disabled: false } | |
] | |
} | |
}; | |
pm.sendRequest(request, function (err, response) { | |
if (err) { | |
reject(err); | |
} | |
const responseBody = cheerio.load(response.stream.toString()); | |
resolve(responseBody); | |
}) | |
}) | |
return promise; | |
} | |
function createTokenRequest( | |
endpoint, | |
clientId, | |
client_secret, | |
code, | |
redirect_uri, | |
code_verifier, | |
grant_type | |
) { | |
var promise = new Promise((resolve, reject) => { | |
const rm = { | |
url: endpoint, | |
method: 'POST', | |
header: { | |
'Accept': 'application/json', | |
'Content-Type': 'application/x-www-form-urlencoded', | |
}, | |
body: { | |
mode: 'urlencoded', | |
urlencoded: [ | |
{ key: "client_id", value: clientId, disabled: false }, | |
{ key: "client_secret", value: client_secret, disabled: false }, | |
{ key: "code", value: code, disabled: false }, | |
{ key: "redirect_uri", value: redirect_uri, disabled: false }, | |
{ key: "grant_type", value: grant_type, disabled: false }, | |
{ key: "code_verifier", value: code_verifier, disabled: false } | |
] | |
} | |
}; | |
pm.sendRequest(rm, function (err, response) { | |
if (err) { | |
reject(err); | |
} | |
resolve(response.json()); | |
}); | |
}) | |
return promise; | |
} | |
const code_verifier = random() + random() + random(); | |
const hash = crypto.SHA256(code_verifier).toString(); | |
const code_challenge = hextob64u(hash); | |
createAuthorizeUri( | |
authorizationEndpoint, | |
clientId, | |
'code', | |
scopes, | |
redirectUrl, | |
'xyz', | |
'form_post', | |
code_challenge, | |
'S256' | |
).then((response) => { | |
if (response.sessionExist) { | |
return response.body; | |
} | |
var token = response.body('input[name="__RequestVerificationToken"]').val(); | |
var returnUrl = response.body('input[name="ReturnUrl"]').val(); | |
const loginRequest = loginEndpoint + '?ReturnUrl=' + encodeURIComponent(returnUrl); | |
return createLoginRequest(loginRequest, '[email protected]', 'password', token); | |
}).then(body => { | |
var code = body('input[name="code"]').val(); | |
return createTokenRequest(tokenEndpoint, | |
clientId, | |
clientSecret, | |
code, | |
redirectUrl, | |
code_verifier, | |
'authorization_code') | |
}) | |
.then(tokenResponse => { | |
console.log(tokenResponse); | |
}) | |
.then((v) => {clearTimeout(interval);}) | |
.catch(console.log) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment