mirror of
https://github.com/usebruno/bruno.git
synced 2025-01-05 05:29:00 +01:00
feat: OAuth 2.0 Client Credentials as Basic Auth - request logic
This commit is contained in:
parent
df35862ee7
commit
0e4a4307ad
@ -268,34 +268,36 @@ const configureRequest = async (
|
||||
if (request.oauth2) {
|
||||
let requestCopy = cloneDeep(request);
|
||||
switch (request?.oauth2?.grantType) {
|
||||
case 'authorization_code':
|
||||
case 'authorization_code': {
|
||||
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
|
||||
const { data: authorizationCodeData, url: authorizationCodeAccessTokenUrl } =
|
||||
const { accessTokenRequestHeaders, accessTokenRequestData, accessTokenRequestUrl } =
|
||||
await resolveOAuth2AuthorizationCodeAccessToken(requestCopy, collectionUid);
|
||||
request.method = 'POST';
|
||||
request.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
request.data = authorizationCodeData;
|
||||
request.url = authorizationCodeAccessTokenUrl;
|
||||
request.headers = accessTokenRequestHeaders;
|
||||
request.data = accessTokenRequestData;
|
||||
request.url = accessTokenRequestUrl;
|
||||
break;
|
||||
case 'client_credentials':
|
||||
}
|
||||
case 'client_credentials': {
|
||||
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
|
||||
const { data: clientCredentialsData, url: clientCredentialsAccessTokenUrl } =
|
||||
const { accessTokenRequestHeaders, accessTokenRequestData, accessTokenRequestUrl } =
|
||||
await transformClientCredentialsRequest(requestCopy);
|
||||
request.method = 'POST';
|
||||
request.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
request.data = clientCredentialsData;
|
||||
request.url = clientCredentialsAccessTokenUrl;
|
||||
request.headers = accessTokenRequestHeaders;
|
||||
request.data = accessTokenRequestData;
|
||||
request.url = accessTokenRequestUrl;
|
||||
break;
|
||||
case 'password':
|
||||
}
|
||||
case 'password': {
|
||||
interpolateVars(requestCopy, envVars, runtimeVariables, processEnvVars);
|
||||
const { data: passwordData, url: passwordAccessTokenUrl } = await transformPasswordCredentialsRequest(
|
||||
requestCopy
|
||||
);
|
||||
const { accessTokenRequestHeaders, accessTokenRequestData, accessTokenRequestUrl } =
|
||||
await transformPasswordCredentialsRequest(requestCopy);
|
||||
request.method = 'POST';
|
||||
request.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
request.data = passwordData;
|
||||
request.url = passwordAccessTokenUrl;
|
||||
request.headers = accessTokenRequestHeaders;
|
||||
request.data = accessTokenRequestData;
|
||||
request.url = accessTokenRequestUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,28 +146,15 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
}
|
||||
|
||||
if (request?.oauth2?.grantType) {
|
||||
let username, password, scope, clientId, clientSecret;
|
||||
switch (request.oauth2.grantType) {
|
||||
case 'password':
|
||||
username = _interpolate(request.oauth2.username) || '';
|
||||
password = _interpolate(request.oauth2.password) || '';
|
||||
clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
scope = _interpolate(request.oauth2.scope) || '';
|
||||
request.oauth2.accessTokenUrl = _interpolate(request.oauth2.accessTokenUrl) || '';
|
||||
request.oauth2.username = username;
|
||||
request.oauth2.password = password;
|
||||
request.oauth2.clientId = clientId;
|
||||
request.oauth2.clientSecret = clientSecret;
|
||||
request.oauth2.scope = scope;
|
||||
request.data = {
|
||||
grant_type: 'password',
|
||||
username,
|
||||
password,
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
scope
|
||||
};
|
||||
request.oauth2.username = _interpolate(request.oauth2.username) || '';
|
||||
request.oauth2.password = _interpolate(request.oauth2.password) || '';
|
||||
request.oauth2.clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
request.oauth2.clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
request.oauth2.clientSecretMethod = _interpolate(request.oauth2.clientSecretMethod) || '';
|
||||
request.oauth2.scope = _interpolate(request.oauth2.scope) || '';
|
||||
break;
|
||||
case 'authorization_code':
|
||||
request.oauth2.callbackUrl = _interpolate(request.oauth2.callbackUrl) || '';
|
||||
@ -175,24 +162,17 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
request.oauth2.accessTokenUrl = _interpolate(request.oauth2.accessTokenUrl) || '';
|
||||
request.oauth2.clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
request.oauth2.clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
request.oauth2.clientSecretMethod = _interpolate(request.oauth2.clientSecretMethod) || '';
|
||||
request.oauth2.scope = _interpolate(request.oauth2.scope) || '';
|
||||
request.oauth2.state = _interpolate(request.oauth2.state) || '';
|
||||
request.oauth2.pkce = _interpolate(request.oauth2.pkce) || false;
|
||||
break;
|
||||
case 'client_credentials':
|
||||
clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
scope = _interpolate(request.oauth2.scope) || '';
|
||||
request.oauth2.accessTokenUrl = _interpolate(request.oauth2.accessTokenUrl) || '';
|
||||
request.oauth2.clientId = clientId;
|
||||
request.oauth2.clientSecret = clientSecret;
|
||||
request.oauth2.scope = scope;
|
||||
request.data = {
|
||||
grant_type: 'client_credentials',
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
scope
|
||||
};
|
||||
request.oauth2.clientId = _interpolate(request.oauth2.clientId) || '';
|
||||
request.oauth2.clientSecret = _interpolate(request.oauth2.clientSecret) || '';
|
||||
request.oauth2.clientSecretMethod = _interpolate(request.oauth2.clientSecretMethod) || '';
|
||||
request.oauth2.scope = _interpolate(request.oauth2.scope) || '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -3,6 +3,10 @@ const crypto = require('crypto');
|
||||
const { authorizeUserInWindow } = require('./authorize-user-in-window');
|
||||
const Oauth2Store = require('../../store/oauth2');
|
||||
|
||||
const encodeClientCredentials = (clientId, clientSecret) => {
|
||||
return 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64');
|
||||
};
|
||||
|
||||
const generateCodeVerifier = () => {
|
||||
return crypto.randomBytes(22).toString('hex');
|
||||
};
|
||||
@ -23,22 +27,34 @@ const resolveOAuth2AuthorizationCodeAccessToken = async (request, collectionUid)
|
||||
let requestCopy = cloneDeep(request);
|
||||
const { authorizationCode } = await getOAuth2AuthorizationCode(requestCopy, codeChallenge, collectionUid);
|
||||
const oAuth = get(requestCopy, 'oauth2', {});
|
||||
const { clientId, clientSecret, callbackUrl, scope, pkce } = oAuth;
|
||||
const data = {
|
||||
grant_type: 'authorization_code',
|
||||
code: authorizationCode,
|
||||
redirect_uri: callbackUrl,
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret
|
||||
};
|
||||
if (pkce) {
|
||||
data['code_verifier'] = codeVerifier;
|
||||
const { clientId, clientSecret, clientSecretMethod, callbackUrl, pkce } = oAuth;
|
||||
|
||||
const accessTokenRequestHeaders = request.headers;
|
||||
accessTokenRequestHeaders['content-type'] = 'application/x-www-form-urlencoded';
|
||||
if (clientSecretMethod === 'client_credentials_basic') {
|
||||
accessTokenRequestHeaders['authorization'] = encodeClientCredentials(clientId, clientSecret);
|
||||
}
|
||||
|
||||
const url = requestCopy?.oauth2?.accessTokenUrl;
|
||||
const accessTokenRequestData = {
|
||||
grant_type: 'authorization_code',
|
||||
code: authorizationCode,
|
||||
redirect_uri: callbackUrl
|
||||
};
|
||||
|
||||
if (clientSecretMethod === 'client_credentials_post') {
|
||||
accessTokenRequestData['client_id'] = clientId;
|
||||
accessTokenRequestData['client_secret'] = clientSecret;
|
||||
}
|
||||
|
||||
if (pkce) {
|
||||
accessTokenRequestData['code_verifier'] = codeVerifier;
|
||||
}
|
||||
|
||||
const accessTokenRequestUrl = requestCopy?.oauth2?.accessTokenUrl;
|
||||
return {
|
||||
data,
|
||||
url
|
||||
accessTokenRequestHeaders,
|
||||
accessTokenRequestData,
|
||||
accessTokenRequestUrl
|
||||
};
|
||||
};
|
||||
|
||||
@ -82,19 +98,30 @@ const getOAuth2AuthorizationCode = (request, codeChallenge, collectionUid) => {
|
||||
const transformClientCredentialsRequest = async (request) => {
|
||||
let requestCopy = cloneDeep(request);
|
||||
const oAuth = get(requestCopy, 'oauth2', {});
|
||||
const { clientId, clientSecret, scope } = oAuth;
|
||||
const data = {
|
||||
grant_type: 'client_credentials',
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret
|
||||
const { clientId, clientSecret, clientSecretMethod, scope } = oAuth;
|
||||
|
||||
const accessTokenRequestHeaders = request.headers;
|
||||
accessTokenRequestHeaders['content-type'] = 'application/x-www-form-urlencoded';
|
||||
if (clientSecretMethod === 'client_credentials_basic') {
|
||||
accessTokenRequestHeaders['authorization'] = encodeClientCredentials(clientId, clientSecret);
|
||||
}
|
||||
|
||||
const accessTokenRequestData = {
|
||||
grant_type: 'client_credentials'
|
||||
};
|
||||
if (scope) {
|
||||
data.scope = scope;
|
||||
accessTokenRequestData.scope = scope;
|
||||
}
|
||||
const url = requestCopy?.oauth2?.accessTokenUrl;
|
||||
if (clientSecretMethod === 'client_credentials_post') {
|
||||
accessTokenRequestData['client_id'] = clientId;
|
||||
accessTokenRequestData['client_secret'] = clientSecret;
|
||||
}
|
||||
|
||||
const accessTokenRequestUrl = requestCopy?.oauth2?.accessTokenUrl;
|
||||
return {
|
||||
data,
|
||||
url
|
||||
accessTokenRequestHeaders,
|
||||
accessTokenRequestData,
|
||||
accessTokenRequestUrl
|
||||
};
|
||||
};
|
||||
|
||||
@ -103,21 +130,34 @@ const transformClientCredentialsRequest = async (request) => {
|
||||
const transformPasswordCredentialsRequest = async (request) => {
|
||||
let requestCopy = cloneDeep(request);
|
||||
const oAuth = get(requestCopy, 'oauth2', {});
|
||||
const { username, password, clientId, clientSecret, scope } = oAuth;
|
||||
const data = {
|
||||
const { username, password, clientId, clientSecret, clientSecretMethod, scope } = oAuth;
|
||||
|
||||
const accessTokenRequestHeaders = request.headers;
|
||||
accessTokenRequestHeaders['content-type'] = 'application/x-www-form-urlencoded';
|
||||
if (clientSecretMethod === 'client_credentials_basic') {
|
||||
accessTokenRequestHeaders['authorization'] = encodeClientCredentials(clientId, clientSecret);
|
||||
}
|
||||
|
||||
const accessTokenRequestData = {
|
||||
grant_type: 'password',
|
||||
username,
|
||||
password,
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret
|
||||
password
|
||||
};
|
||||
if (scope) {
|
||||
data.scope = scope;
|
||||
accessTokenRequestData.scope = scope;
|
||||
}
|
||||
const url = requestCopy?.oauth2?.accessTokenUrl;
|
||||
if (clientSecretMethod === 'client_credentials_post') {
|
||||
accessTokenRequestData['client_id'] = clientId;
|
||||
if(clientSecret) {
|
||||
accessTokenRequestData['client_secret'] = clientSecret;
|
||||
}
|
||||
}
|
||||
|
||||
const accessTokenRequestUrl = requestCopy?.oauth2?.accessTokenUrl;
|
||||
return {
|
||||
data,
|
||||
url
|
||||
accessTokenRequestHeaders,
|
||||
accessTokenRequestData,
|
||||
accessTokenRequestUrl
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -286,6 +286,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
password: get(request, 'auth.oauth2.password'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
clientSecretMethod: get(request, 'auth.oauth2.clientSecretMethod'),
|
||||
scope: get(request, 'auth.oauth2.scope')
|
||||
};
|
||||
break;
|
||||
@ -297,6 +298,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
clientSecretMethod: get(request, 'auth.oauth2.clientSecretMethod'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
state: get(request, 'auth.oauth2.state'),
|
||||
pkce: get(request, 'auth.oauth2.pkce')
|
||||
@ -308,6 +310,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
clientSecretMethod: get(request, 'auth.oauth2.clientSecretMethod'),
|
||||
scope: get(request, 'auth.oauth2.scope')
|
||||
};
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user