Skip to Content
Personal Insights
Author's profile photo Dilip Kumar Krishnadev Pandey

Get SharePoint AccessToken using SAP PI UDF

Parent blog Integrate SharePoint using SAP PI

Overview:

SharePoint supports OAuth to authorize the application request instead of credentials (username and password) while calling SharePoint-REST to perform CRUD operations.

Open Authorization (OAuth) is an open protocol for authorization. OAuth enables secure authorization from desktop and web applications in a simple and standard way. It lets users approve an application to act on their behalf without sharing their user name and password.

To perform any Read/Write operation using respective SharePoint-REST service, first we require “SharePoint Access token” for authentication.

To fetch “SharePoint Access token” following REST-details can be used:

  • REST-URL:   https://accounts.accesscontrol.windows.net/<tenantID>/tokens/OAuth/2
  • Method:         POST
  • Headers:       Content-Type: “application/x-www-form-urlencoded”
  • Body: (Request Parameter format)
    • grant_type=client_credentials
      &client_id=<shp_clientId>@<shp_tenantId>
      &client_secret=<shp_clientSecret>
      &resource=00000003-0000-0ff1-ce00-000000000000/<org_Shp_Host>@<shp_tenantId>
  • Note: Following details are specific to Organization’s SharePoint data:
    • <shp_clientId>:          Client ID is a GUID for the SharePoint Add in
    • <shp_tenantId>:         Tenant ID is SharePoint Online Site Realm
    • <shp_clientSecret>:   Client Secret is the password for the add-ins.
    • <org_Shp_Host>:       Organisation’s SharePoint host name

SAP PI UDF example to fetch SharePoint Access Token:

Java Imports required in UDF are as :
  • java.net.URL
    java.net.URLConnection
    java.net.HttpURLConnection
Java Input parameters:
Java UDF Code:
public String getShpToken(String shp_clientId, String shp_tenantId, String shp_clientSecret, String shp_clientDomain, Container container) throws StreamTransformationException{
		 /**
		 * This function helps to get SharePoint Access Token. SharePoint Access
		 * Token is required to authenticate SharePoint REST service while performing Read/Write events. 
		 * SharePoint REST-URL to get access token is as:
		 * 	https://accounts.accesscontrol.windows.net/<tenantID>/tokens/OAuth/2
		 * 
		 * Input required related to SharePoint are as: 
		 * 1. shp_clientId 
		 * 2. shp_tenantId
		 * 3. shp_clientSecret 		
		 */

		String accessToken = "";
		try {

			// AccessToken url
			String wsURL = "https://accounts.accesscontrol.windows.net/" + shp_tenantId + "/tokens/OAuth/2";

			URL url = new URL(wsURL);
			URLConnection connection = url.openConnection();
			HttpURLConnection httpConn = (HttpURLConnection) connection;

			// Set header
			httpConn.setRequestProperty("Content-Type",	"application/x-www-form-urlencoded");
			httpConn.setDoOutput(true);
			httpConn.setDoInput(true);
			httpConn.setRequestMethod("POST");

			// Prepare RequestData
			String jsonParam = "grant_type=client_credentials" 
					+ "&client_id=" + shp_clientId + "@" + shp_tenantId 
					+ "&client_secret=" + shp_clientSecret
					+ "&resource=00000003-0000-0ff1-ce00-000000000000/<org_Shp_Host>@" + shp_tenantId;
			//Here, <org_Shp_Host> is "Origanisations's Sharepoint Host"

			// Send Request
			DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
			wr.writeBytes(jsonParam);
			wr.flush();
			wr.close();

			// Read the response.
			InputStreamReader isr = null;
			if (httpConn.getResponseCode() == 200) {
				isr = new InputStreamReader(httpConn.getInputStream());
			} else {
				isr = new InputStreamReader(httpConn.getErrorStream());
			}

			BufferedReader in = new BufferedReader(isr);
			String responseString = "";
			String outputString = "";

			// Write response to a String.
			while ((responseString = in.readLine()) != null) {
				outputString = outputString + responseString;
			}

			// Extracting accessToken from string, here response (outputString)is a Json format string
			if (outputString.indexOf("access_token\":\"") > -1) {
				int i1 = outputString.indexOf("access_token\":\"");
				String str1 = outputString.substring(i1 + 15);
				int i2 = str1.indexOf("\"}");
				String str2 = str1.substring(0, i2);
				accessToken = str2;
			}
		} catch (Exception e) {
			accessToken = "Error: " + e.getMessage();			
		}
		return accessToken;
}
Testing Screen of UDF inside Graphical Map:

Note:

Before, consuming SharePoint-APIs, we should always check its behavior using standard tools like ‘POSTMAN’ etc, to avoid unnecessary confusion (like in case if error occurs due to UDF code or Service credentials).

TEST using POSTMAN Tool:

Set Header:

Set-Body: Method-01 | We can set token request in BODY part as below:

 

Set-Body: Method-02 | We can set token request like below too:

 

Here, If we get Error “AADSTS7000215: Invalid client secret is provided

Then Root-Cause is, that, Client_secret had “few unnecessary characters like + and /

And Resolution is to encoded Client_Secret. The encoded client_secret you can get from original using any online Encode/Decode-String tool/Link.

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Apu Das
      Apu Das

      Hi Dilip,

      OAuth 2.0 authentication for REST services can be done directly now in CC itself by selecting OAuth 2.0 Grants Type Flow in PI 7.5.

      You can check below blog -

      https://blogs.sap.com/2017/07/21/sap-po-rest-integration-with-salesforce-oauth/

      Thanks,

      Apu

       

      Author's profile photo Rajesh PS
      Rajesh PS

      Hello Dilip Kumar Krishnadev Pandey

       

      Your valuable thoughts on this please.

       

      https://answers.sap.com/questions/12872081/how-to-read-and-write-oauh-access-token.html

       

      Thanks in advance!

      Author's profile photo uddeshya pratik
      uddeshya pratik

      Hi Dilip,

       

      Using your above java code i have tried to get the access token from share point but getting an error i.e. but when i am trying with postman its giving proper response using the same access key and other credentials .I am attaching the code and the postman screenshot for your response.

      {"error":"invalid_client","error_description":"AADSTS7000215: Invalid client secret is provided.\r\nTrace ID: 6a71613e-4dea-464b-8141-28fef1fd9100\r\nCorrelation ID: 4e54ec74-63b1-4fbc-89e0-63e7f17dc519\r\nTimestamp: 2020-06-19 20:04:28Z","error_codes":[7000215],"timestamp":"2020-06-19 20:04:28Z","trace_id":"6a71613e-4dea-464b-8141-28fef1fd9100","correlation_id":"4e54ec74-63b1-4fbc-89e0-63e7f17dc519","error_uri":"https://accounts.accesscontrol.windows.net/error?code=7000215"}

       

       

      Java Code:

      ####################

       

       

      import java.io.BufferedReader;
      import java.io.DataOutputStream;
      import java.io.InputStreamReader;
      import java.net.HttpURLConnection;
      import java.net.URL;
      import java.net.URLConnection;

      public class SharepointAccessClass {

      /**
      * upload a file to a sharepoint library
      */
      public static void main(String[] args) throws Exception{
      /**
      * This function helps to get SharePoint Access Token. SharePoint Access
      * Token is required to authenticate SharePoint REST service while performing Read/Write events.
      * SharePoint REST-URL to get access token is as:
      * https://accounts.accesscontrol.windows.net/<tenantID>/tokens/OAuth/2
      *
      * Input required related to SharePoint are as:
      * 1. shp_clientId
      * 2. shp_tenantId
      * 3. shp_clientSecret
      */

      String accessToken = "";
      String shp_clientId="f83e1c66-f64d-49a1-85e2-207e47092918";
      String shp_tenantId="42150afd-062a-4a0f-81b9-0323526054cc";
      String shp_clientSecret="28t3QzULzpYlhJhHqt8BTGn+xY/WmQQcokb1SxKryNI=";
      try {

      // AccessToken url
      String wsURL = "https://accounts.accesscontrol.windows.net/" + shp_tenantId + "/tokens/OAuth/2";

      URL url = new URL(wsURL);
      URLConnection connection = url.openConnection();
      HttpURLConnection httpConn = (HttpURLConnection) connection;

      // Set header
      httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
      httpConn.setRequestProperty("Content-Length", "0");
      httpConn.setRequestProperty("Host", "<calculated when request is sent>");
      httpConn.setDoOutput(true);
      httpConn.setDoInput(true);
      httpConn.setRequestMethod("POST");

      // Prepare RequestData

      String jsonParam = "grant_type=client_credentials"
      + "&client_id=" + shp_clientId + "@" + shp_tenantId
      + "&client_secret=" + shp_clientSecret
      + "&resource=00000003-0000-0ff1-ce00-000000000000/naveedtest.sharepoint.com@" + shp_tenantId;
      //Here, <org_Shp_Host> is "Origanisations's Sharepoint Host"

      // Send Request
      DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
      wr.writeBytes(jsonParam);
      wr.flush();
      wr.close();

      // Read the response.
      InputStreamReader isr = null;
      if (httpConn.getResponseCode() == 200) {
      isr = new InputStreamReader(httpConn.getInputStream());
      } else {
      isr = new InputStreamReader(httpConn.getErrorStream());
      }

      BufferedReader in = new BufferedReader(isr);
      String responseString = "";
      String outputString = "";

      // Write response to a String.
      while ((responseString = in.readLine()) != null) {
      outputString = outputString + responseString;
      System.out.println(outputString);
      }

      // Extracting accessToken from string, here response (outputString)is a Json format string
      if (outputString.indexOf("access_token\":\"") > -1) {
      int i1 = outputString.indexOf("access_token\":\"");
      String str1 = outputString.substring(i1 + 15);
      int i2 = str1.indexOf("\"}");
      String str2 = str1.substring(0, i2);
      accessToken = str2;
      }
      } catch (Exception e) {
      accessToken = "Error: " + e.getMessage();
      }
      }
      }

       

       

      Thanks in Advance.

       

      Cheers,

      Uddeshya

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Uddeshya,

      Sorry for late response.

      • Your clientSecret has special chars. While consuming it in JavaPgm just, use its encoded value.
      • For example: if your value is below:
      • shp_clientSecret=”28t3QzULzpYlhJhHqt8BTGn+xY/WmQQcokb1SxKryNI=”;
      • Then its encoded value will be like below:
      • shp_clientSecret=”28t3QzULzpYlhJhHqt8BTGn%2BxY%2FWmQQcokb1SxKryNI%3D”;

      Thanks & Regards,

      Dilip P.

      Author's profile photo Varun K
      Varun K

      Hi Team,

       

      I have a similar requirement, but token(QAuthorization) is passed in Response Header as shown below instead of payload, How to retrieve token from header.

      Can this be achieved using UDF ?

      Json%20Request

      Json Request

       

      Thanks,

      Varun

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Varun,

      Sorry for late response, by now you may have manged this.

      As per your case, using JavaPgm, I would be reading the ResponseHeader to get oAuthorizationToken.

      Thanks & Regards,

      Dilip P.

      Author's profile photo Amarnath M
      Amarnath M

      Hi

      When I do testing in Mapping, I am getting empty result.

      Any idea what could I be missing?

      I just modified url and request data as per my request.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Amarnath,

      Sorry, for late reply, I hope by now, you may have already addressed the issue.

      SharePoint has given dedicated URI and it's protocol for each supported action, that can be followed. And in case of error, plz focus on type of error code returned from API

      Thanks & Regards,

      Dilip

      Author's profile photo Doug Allard
      Doug Allard

      Excellent post Dilip, you're a life saver
      I know Java but not PI
      Got my access token UDF working
      Not sure how to plug it in to do the report calls
      But at least I know PJ can handle the various types of API calls

      Well done

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Doug,

      Good to hear your input.

      Just for information, you can use JavaMap, where you can club AccessToken call and next data-POST API.

      I had a requirement, where I was having 10K+ data from source application and I had to POST them into SharePoint in File-Format having 200 records per file. So, I had used JavaMap

      • to get 10K records from one API (source data provider)
      • then calling Sharepoint-Access-Token
      • then splitting the 10K output (of 1st API) into 200 each set,
      • and keep calling SharePoint-Data-POST-API in loop to post the data in file format (200 records per file at max)

      You can refere below JavaMap code examples:

      https://blogs.sap.com/2018/08/26/post-pdf-file-in-sharepoint-using-sap-pi-java-map/

      https://blogs.sap.com/2017/11/29/sharepoint-bulk-insert-using-java-program/

       

      Thanks & Regards,

      Dilip