From 3192d9df9069cb4251f746f02b31c6eac9f4aba3 Mon Sep 17 00:00:00 2001
From: sfdrogojan <42441166+sfdrogojan@users.noreply.github.com>
Date: Wed, 15 May 2019 13:28:02 +0300
Subject: [PATCH] Added OAuth2 support
* Added OAuth2 support.
* Added context switching support for OAuth2
* Fixed bug caused by accessToken expiration.
---
README.md | 14 +--
fuelsdk.properties.template | 5 +
pom.xml | 2 +-
.../com/exacttarget/fuelsdk/ETClient.java | 93 +++++++++++++++++--
.../exacttarget/fuelsdk/ETRestConnection.java | 2 +-
.../exacttarget/fuelsdk/ETSoapConnection.java | 4 +-
6 files changed, 99 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
index 92a83507..91d65004 100755
--- a/README.md
+++ b/README.md
@@ -25,16 +25,10 @@ Java platform. Among other things, the SDK:
For more information about the Java SDK and how to use it, please see
the Javadocs at http://salesforce-marketingcloud.github.io/FuelSDK-Java/.
-New Features in Version 1.3.2
+New Features in Version 1.4.0
------------
-* Added support for your tenant’s endpoints - [More Details](https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/your-subdomain-tenant-specific-endpoints.htm)
-* REST, Auth endpoints are configurable. If not specified in the fuelsdk.properties file,
-they are defaulted to "https://www.exacttargetapis.com" for REST and
-"https://auth.exacttargetapis.com" for Auth.
-* SOAP endpoint is also configurable. If not specified in the fuelsdk.properties file,
-it is defaulted to "https://webservice.exacttarget.com/service.asmx"
-* Removed the legacyToken query string parameter support.
-
+* Added support for OAuth2 authentication - [More Details](https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/integration-considerations.htm)
+* To enable OAuth2 authentication, set `useOAuth2Authentication=true` in the fuelsdk.properties file.
Installation
------------
@@ -44,7 +38,7 @@ The easiest way to install the Java SDK is via Maven—simply add the follow
com.github.salesforce-marketingcloud
fuelsdk
- 1.3.2
+ 1.4.0
Maven will automatically resolve, download, and install all dependencies for you.
diff --git a/fuelsdk.properties.template b/fuelsdk.properties.template
index 8e932256..1acf9b9d 100755
--- a/fuelsdk.properties.template
+++ b/fuelsdk.properties.template
@@ -1,4 +1,9 @@
clientId=xxxxxxx
clientSecret=###########################
authEndpoint=https://auth.exacttargetapis.com
+endpoint=https://########.rest.marketingcloudapis.com
+soapEndpoint=https://########.soap.marketingcloudapis.com/service.asmx
+useOAuth2Authentication=false
+accountId=
+scope=
dataExtensionFolderId=
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 50e9fc05..89c3fde1 100755
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.github.salesforce-marketingcloud
fuelsdk
- 1.3.2
+ 1.4.0
Salesforce Marketing Cloud Java SDK
Salesforce Marketing Cloud Java SDK
https://github.com/salesforce-marketingcloud/FuelSDK-Java
diff --git a/src/main/java/com/exacttarget/fuelsdk/ETClient.java b/src/main/java/com/exacttarget/fuelsdk/ETClient.java
index bde330fa..6f4d394f 100755
--- a/src/main/java/com/exacttarget/fuelsdk/ETClient.java
+++ b/src/main/java/com/exacttarget/fuelsdk/ETClient.java
@@ -66,6 +66,8 @@ public class ETClient {
"https://auth.exacttargetapis.com";
private static final String PATH_REQUESTTOKEN =
"/v1/requestToken";
+ private static final String PATH_OAUTH2TOKEN =
+ "/v2/token";
private static final String PATH_ENDPOINTS_SOAP =
"/platform/v1/endpoints/soap";
private static final String DEFAULT_SOAP_ENDPOINT =
@@ -100,6 +102,9 @@ public class ETClient {
private static long soapEndpointExpiration = 0;
private static String fetchedSoapEndpoint = null;
private static final long cacheDurationInMillis = 1000 * 60 * 10; // 10 minutes
+ private boolean useOAuth2Authentication;
+ private String accountId;
+ private String scope;
/**
* Class constructor, Initializes a new instance of the class.
@@ -154,11 +159,15 @@ public ETClient(ETConfiguration configuration)
gson = gsonBuilder.create();
}
+ useOAuth2Authentication = configuration.isTrue("useOAuth2Authentication") ? true : false;
+ accountId = configuration.get("accountId");
+ scope = configuration.get("scope");
+
if (clientId != null && clientSecret != null) {
authConnection = new ETRestConnection(this, authEndpoint, true);
requestToken();
restConnection = new ETRestConnection(this, endpoint);
- FetchSoapEndpoint();
+ fetchSoapEndpoint();
soapConnection = new ETSoapConnection(this, soapEndpoint, accessToken);
} else {
if (username == null || password == null) {
@@ -191,7 +200,11 @@ public ETClient(ETConfiguration configuration)
}
}
- private void FetchSoapEndpoint() {
+ private void fetchSoapEndpoint() {
+ if(useOAuth2Authentication) {
+ return;
+ }
+
if (soapEndpoint == null || soapEndpoint.equals("")) {
//
// If a SOAP endpoint isn't specified automatically determine it:
@@ -313,6 +326,70 @@ public synchronized String requestToken()
return requestToken(null);
}
+ private synchronized String requestOAuth2Token()
+ throws ETSdkException
+ {
+ if (clientId == null || clientSecret == null) {
+ // no-op
+ return null;
+ }
+ //
+ // Construct the JSON payload.
+ //
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("client_id", clientId);
+ jsonObject.addProperty("client_secret", clientSecret);
+ jsonObject.addProperty("grant_type", "client_credentials");
+ if(accountId != null && accountId.length() > 0)
+ {
+ jsonObject.addProperty("account_id", accountId);
+ }
+ if(scope != null && scope.length() > 0)
+ {
+ jsonObject.addProperty("scope", scope);
+ }
+
+ String requestPayload = gson.toJson(jsonObject);
+
+ ETRestConnection.Response response = null;
+
+ response = authConnection.post(PATH_OAUTH2TOKEN, requestPayload);
+
+ if (response.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new ETSdkException("error obtaining OAuth2 access token "
+ + "("
+ + response.getResponseCode()
+ + " "
+ + response.getResponseMessage()
+ + ")");
+ }
+
+ //
+ // Parse the JSON response into the appropriate instance
+ // variables:
+ //
+
+ String responsePayload = response.getResponsePayload();
+
+ JsonParser jsonParser = new JsonParser();
+ jsonObject = jsonParser.parse(responsePayload).getAsJsonObject();
+ this.accessToken = jsonObject.get("access_token").getAsString();
+ this.expiresIn = jsonObject.get("expires_in").getAsInt();
+ this.endpoint = jsonObject.get("rest_instance_url").getAsString();
+ this.soapEndpoint = jsonObject.get("soap_instance_url").getAsString() + "service.asmx";
+
+ //
+ // Calculate the token expiration time. As before,
+ // System.currentTimeMills() is in milliseconds so
+ // we multiply expiresIn by 1000:
+ //
+
+ tokenExpirationTime = System.currentTimeMillis() + (expiresIn * 1000);
+
+ return accessToken;
+ }
+
/**
*
* @param refreshToken The refresh token
@@ -321,6 +398,10 @@ public synchronized String requestToken()
public synchronized String requestToken(String refreshToken)
throws ETSdkException
{
+ if(useOAuth2Authentication){
+ return requestOAuth2Token();
+ }
+
if (clientId == null || clientSecret == null) {
// no-op
return null;
@@ -418,15 +499,13 @@ public synchronized String refreshToken()
}
logger.debug("refreshing access token...");
-
- if (refreshToken == null) {
- throw new ETSdkException("refreshToken == null");
- }
}
requestToken(refreshToken);
- soapConnection.setAccessToken(accessToken);
+ if(soapConnection != null) {
+ soapConnection.setAccessToken(accessToken);
+ }
return accessToken;
}
diff --git a/src/main/java/com/exacttarget/fuelsdk/ETRestConnection.java b/src/main/java/com/exacttarget/fuelsdk/ETRestConnection.java
index 484c8b09..9770949a 100755
--- a/src/main/java/com/exacttarget/fuelsdk/ETRestConnection.java
+++ b/src/main/java/com/exacttarget/fuelsdk/ETRestConnection.java
@@ -240,7 +240,7 @@ private HttpURLConnection sendRequest(URL url, Method method, String payload)
try {
connection = (HttpURLConnection) url.openConnection();
- connection.setRequestProperty("User-Agent", "FuelSDK-Java-v1.3.2-REST-"+method+"-"+object);
+ connection.setRequestProperty("User-Agent", "FuelSDK-Java-v1.4.0-REST-"+method+"-"+object);
connection.setRequestMethod(method.toString());
} catch (ProtocolException ex) {
throw new ETSdkException("error setting request method: " + method.toString(), ex);
diff --git a/src/main/java/com/exacttarget/fuelsdk/ETSoapConnection.java b/src/main/java/com/exacttarget/fuelsdk/ETSoapConnection.java
index e8578de7..54d70d02 100755
--- a/src/main/java/com/exacttarget/fuelsdk/ETSoapConnection.java
+++ b/src/main/java/com/exacttarget/fuelsdk/ETSoapConnection.java
@@ -234,12 +234,12 @@ public Soap getSoap() {
}
public Soap getSoap(String m) {
- soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.3.2-SOAP-"+m);
+ soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.4.0-SOAP-"+m);
return soap;
}
public Soap getSoap(String m, String o) {
- soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.3.2-SOAP-"+m+"-"+o);
+ soapClient.getRequestContext().put("HTTP_HEADER_USER_AGENT", "FuelSDK-Java-v1.4.0-SOAP-"+m+"-"+o);
return soap;
}