Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Added
- authentication/OfflineTokenRefresh.js - refresh oauth2 offline tokens
- httpsender/AddBearerTokenHeader.js - refresh oauth2 offline tokens

## [11] - 2021-09-07
### Added
Expand Down
72 changes: 72 additions & 0 deletions authentication/OfflineTokenRefresh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* This script is intended to be used along with httpsender/AddBearerTokenHeader.js to
* handle an OAUTH2 offline token refresh workflow.
*
* authentication/OfflineTokenRefresher.js will automatically fetch the new access token for every unauthorized
* request determined by the "Logged Out" or "Logged In" indicator previously set in Context -> Authentication.
*
* httpsender/AddBearerTokenHeader.js will add the new access token to all requests in scope
* made by ZAP (except the authentication ones) as an "Authorization: Bearer [access_token]" HTTP Header.
*
* @author Laura Pardo <lpardo at redhat.com>
*/

var HttpRequestHeader = Java.type("org.parosproxy.paros.network.HttpRequestHeader");
var HttpHeader = Java.type("org.parosproxy.paros.network.HttpHeader");
var URI = Java.type("org.apache.commons.httpclient.URI");
var ScriptVars = Java.type('org.zaproxy.zap.extension.script.ScriptVars');


function authenticate(helper, paramsValues, credentials) {

var token_endpoint = paramsValues.get("token_endpoint");
var client_id = paramsValues.get("client_id");
var refresh_token = credentials.getParam("refresh_token");

// Build body
var refreshTokenBody = "client_id=" + client_id;
refreshTokenBody+= "&grant_type=refresh_token";
refreshTokenBody+= "&refresh_token=" + refresh_token;

// Build header
var tokenRequestURI = new URI(token_endpoint, false);
var tokenRequestMethod = HttpRequestHeader.POST;
var tokenRequestMainHeader = new HttpRequestHeader(tokenRequestMethod, tokenRequestURI, HttpHeader.HTTP11);

// Build message
var tokenMsg = helper.prepareMessage();
tokenMsg.setRequestBody(refreshTokenBody);
tokenMsg.setRequestHeader(tokenRequestMainHeader);
tokenMsg.getRequestHeader().setContentLength(tokenMsg.getRequestBody().length());

// Make the request and receive the response
helper.sendAndReceive(tokenMsg, false);

// Parse the JSON response and save the new access_token in a global var
// we will replace the Authentication header in AddBearerTokenHeader.js
var json = JSON.parse(tokenMsg.getResponseBody().toString());
var access_token = json['access_token'];

if (access_token){
ScriptVars.setGlobalVar("access_token", access_token);
}else{
print("Error getting access token")
}

return tokenMsg;
}


function getRequiredParamsNames(){
return ["token_endpoint", "client_id"];
}


function getOptionalParamsNames(){
return [];
}


function getCredentialsParamsNames(){
return ["access_token", "refresh_token"];
}
27 changes: 27 additions & 0 deletions httpsender/AddBearerTokenHeader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This script is intended to be used along with authentication/OfflineTokenRefresher.js to
* handle an OAUTH2 offline token refresh workflow.
*
* authentication/OfflineTokenRefresher.js will automatically fetch the new access token for every unauthorized
* request determined by the "Logged Out" or "Logged In" indicator previously set in Context -> Authentication.
*
* httpsender/AddBearerTokenHeader.js will add the new access token to all requests in scope
* made by ZAP (except the authentication ones) as an "Authorization: Bearer [access_token]" HTTP Header.
*
* @author Laura Pardo <lpardo at redhat.com>
*/

var HttpSender = Java.type('org.parosproxy.paros.network.HttpSender');
var ScriptVars = Java.type('org.zaproxy.zap.extension.script.ScriptVars');

function sendingRequest(msg, initiator, helper) {

// add Authorization header to all request in scope except the authorization request itself
if (initiator !== HttpSender.AUTHENTICATION_INITIATOR && msg.isInScope()) {
msg.getRequestHeader().setHeader("Authorization", "Bearer " + ScriptVars.getGlobalVar("access_token"));
}

return msg;
}

function responseReceived(msg, initiator, helper) {}