Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
92003ee
Important files assembled for OAuth2 testing
prayascoriolis Aug 29, 2024
1c7323b
resolved paths error
prayascoriolis Aug 29, 2024
7d35f86
commenting plugin in pom.xml for ruuning kfka test
prayascoriolis Aug 31, 2024
8b40305
Merge branch 'master' into ISSUE-193-OAuth2-Support
prayascoriolis Aug 31, 2024
aba383b
Description improved
authorjapps Aug 6, 2024
0603dbf
Install docker compose manually and try
authorjapps Aug 31, 2024
19690a1
Merge branch 'ISSUE-193-OAuth2-Support' of https://github.com/prayasc…
prayascoriolis Aug 31, 2024
d349285
uncommenting plugin in pom.xml for ruuning kfka test
prayascoriolis Aug 31, 2024
ef2b685
grant_type fetched from host.properties, name-value pair in post url
prayascoriolis Sep 5, 2024
159be2b
separate assertions & unit test class used for refresh & acces token …
prayascoriolis Sep 6, 2024
ea564c5
Access Token workflow implemented
prayascoriolis Sep 6, 2024
3f35c99
host.properties modified for access and refresh token
prayascoriolis Sep 6, 2024
aab323b
updated the comments for oauth2 code
prayascoriolis Sep 10, 2024
e529bae
fix: resolve issue with mock server not matching incoming requests
prayascoriolis Sep 11, 2024
adcb897
removed duplicate localhost_REST_fake_end_points_stubs.json from http…
prayascoriolis Sep 11, 2024
14d65c9
end to end access token implemetation with fake REST end points
prayascoriolis Sep 11, 2024
626f82e
Merge branch 'master' into ISSUE-193-OAuth2-Support
prayascoriolis Oct 29, 2024
0cc5aef
accountsUrl changed to accessTokenUrl, class names changed to CamelCa…
prayascoriolis Oct 30, 2024
2efa3c6
Merge branch 'ISSUE-193-OAuth2-Support' of https://github.com/prayasc…
prayascoriolis Oct 30, 2024
e7106cf
Merge branch 'master' into ISSUE-193-OAuth2-Support
prayascoriolis Feb 27, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.jsmart.zerocode.core.httpclient.oauth2;

import java.util.Map;
import java.util.Timer;

import org.jsmart.zerocode.core.httpclient.BasicHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import org.apache.http.client.methods.RequestBuilder;

/**
* @author santhoshTpixler
*
*/


/*
* Note: This implementation supports the OAuth2.0 with refresh_token
*
* Reference: https://tools.ietf.org/html/rfc6749#page-11
*
*
* 1. The refresh_token, access_token URL, client_id and client_secret
* should be generated by the user and stored in the properties file
* mentioned in the @TargetEnv("host.properties").
* 2. For generating the refresh token REST Client such as Insomnia (https://insomnia.rest/) can
* be used.
*
* Note: Postman cannot be used as it does not show the refresh token.
*/
public class OAuth2HttpClient extends BasicHttpClient {

private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2HttpClient.class);

/*
* Properties to be fetched from the host.properties
*/
private static final String CLIENT_ID = "client_id";
private static final String CLIENT_SECRET = "client_secret";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String ACCOUNTS_URL = "accounts_url";

/*
* If the Authorization header contains the replacement value as specified by the
* below constant, then it is replaced with the valid access token
*/
private static final String ACCESS_TOKEN_REPLACEMENT_VALUE = "DIY";
/*
* Time interval in which the accessToken should be renewed
*/
private static final long REFRESH_INTERVAL = 3540000;

private OAuth2Impl oauth2 = null;

@Inject
public OAuth2HttpClient(@Named(CLIENT_ID) String clientId, @Named(CLIENT_SECRET) String clientSecret,
@Named(REFRESH_TOKEN) String refreshToken, @Named(ACCOUNTS_URL) String accountsURL) {
this.oauth2 = new OAuth2Impl(clientId, clientSecret, refreshToken, accountsURL);
Timer timer = new Timer();
timer.schedule(oauth2, 0, REFRESH_INTERVAL);
synchronized (oauth2) {
try {
oauth2.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

@Override
public RequestBuilder handleHeaders(Map<String, Object> headers, RequestBuilder requestBuilder) {
String authorization = (String) headers.get("Authorization");
if (authorization != null && authorization.equals(ACCESS_TOKEN_REPLACEMENT_VALUE)) {
headers.put("Authorization", oauth2.getAccessToken());
LOGGER.info("Token injected into header.");
}
return super.handleHeaders(headers, requestBuilder);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.jsmart.zerocode.core.httpclient.oauth2;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author santhoshTpixler
*
*/

/*
* Note: This implementation supports the OAuth2.0 with refresh_token
*
* Reference: https://tools.ietf.org/html/rfc6749#page-11
*/
public class OAuth2Impl extends TimerTask {
private String clienId;
private String clientSecret;
private String refreshToken;
private String accessTokenURL;

private String accessToken;
private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2Impl.class);

public OAuth2Impl(String clientId, String clientSecret, String refreshToken, String accountsUrl) {
this.clienId = clientId;
this.clientSecret = clientSecret;
this.refreshToken = refreshToken;
this.accessTokenURL = accountsUrl;
}

@Override
public void run() {
generateToken();
}

public synchronized String getAccessToken() {
return accessToken;

}

private synchronized void setAccessToken(String token) {
this.accessToken = "Bearer " + token;
}

/**
* Makes a POST request to the accessTokenURL to fetch the accesstoken
*/
private synchronized void generateToken() {
try (CloseableHttpClient client = HttpClients.createDefault()) {


StringBuilder URL = new StringBuilder(accessTokenURL);
URL.append('?');
URL.append("refresh_token=" + refreshToken);
URL.append("&client_id=" + clienId);;
URL.append("&client_secret=" + clientSecret);
URL.append("&grant_type=refresh_token");
HttpPost post = new HttpPost(URL.toString());


/*
* Below code was not compatible with simulator. In production kindly make
* use of the below code.
*/

/*
* List<NameValuePair> nameValuePairs = new ArrayList<>(4);
* nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
* nameValuePairs.add(new BasicNameValuePair("client_secret", clientSecret));
* nameValuePairs.add(new BasicNameValuePair("client_id", clienId));
* nameValuePairs.add(new BasicNameValuePair("grant_type", "refresh_token"));
* post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
*/

JSONObject jsonRespone = null;
try (CloseableHttpResponse response = client.execute(post);) {
try (InputStream stream = response.getEntity().getContent()) {
jsonRespone = new JSONObject(new JSONTokener(stream));
}
}
if (accessToken == null) {
setAccessToken(jsonRespone.getString("access_token"));
this.notifyAll();
} else {
setAccessToken(jsonRespone.getString("access_token"));
}
} catch (Exception e) {
LOGGER.error("Cannot fetch access token from IAM", e);
}

}

}
Loading
Loading