SharePoint Online and Salesforce Integration

SharePoint Online and Salesforce are two different cloud platforms, provided as “Software as a Service” from two different vendors.

SharePoint is a cloud-based “Software as a Service” using which organizations can share content with colleagues, partners, and customers. SharePoint online also provides flexibility to access it from anywhere, i.e. home or office or wherever Internet connectivity is available, and from any device, i.e. mobile/compact.

At the other end of the spectrum,  Salesforce is a cloud-based customer relationship management software solution for sales, service, marketing, collaboration, analytics, and building reports.

Both the above can be considered as “Software as a Service” platforms.

In most business situations, there may be a use case, where business users would like to seamlessly obtain data from Salesforce on to SharePoint online, so that, the information can be collaborated from one single platform, instead of two different places.

In this blog, I will explain the concept and steps required to integrate Salesforce with the SharePoint Online site, so that, information updated or created in Salesforce will, in real-time, be updated and created in SharePoint online site.

When the question arises as to how to write data in SharePoint online, the first hurdle is to remotely authenticate the user against it, and in order to remotely authenticate the user, the best way available is REST api.

You need to make few rest calls to get the authentication piece as given below:

  • Get the security token
  • Get the access token
  • Get the request digest

The above rest call should be translated into an apex class which is supported by force.com

The first task is to get the SharePoint online security token, which can be obtained by posting XML as the request body to https://login.microsoftonline.com/extSTS.srf. In the XML you need to pass on account credentials which has at least contribute access.

The above request would fetch a response security token which is needed to get the access token.

In order to get the access token, again a rest call is required to be posted to the following URL with the security token as the request body:

https://yourdomain.sharepointonline.com/_forms/default.aspx?wa=wsignin1.0

The rest call with the request body including security token to the above URL would fetch a response, which would contain cookies and these cookies must be included in all the subsequent rest calls.

After the above operation, you need to have the request digest. The request digest is obtained by posting the rest call along with the access token and the obtained cookies to the following URL:

https://yourdoamin.sharepointonline.com/_api/contextinfo.

The rest call that is posted to the above URL will fetch the response along with the request digest. Please note that the entire contents of the “FormDigestValue” tag would be required which includes the date-time portion as well as time zone offset.

All the above steps have to be carried out in terms of a global apex class, and call the apex class with the trigger in salesforce.

Apex class source code is as given below: 

global class SharePointOnlineWebserviceCallout{
 @future (callout=true)
 Public static Void GetAuthentication(string AccountTitle)
 {
 string body = '';
 string formattedCookie = '';
 string output = '';
 string cookie = '';
 string token = '';
 string username = 'account@sharepoint.com';
 string password = 'Password';
 string host = 'https://yourdoamin.sharepointonline.com';
 string tokenRequestXml ='<s:Envelope ' +
 'xmlns:s='http://www.w3.org/2003/05/soap-envelope' ' +
 'xmlns:a='http://www.w3.org/2005/08/addressing' ' +
 'xmlns:u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'> ' +
 '<s:Header>' +
 '<a:Action s_mustUnderstand='1'>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>' +
 '<a:ReplyTo> ' +
 '<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> ' +
 '</a:ReplyTo>' +
 '<a:To s_mustUnderstand='1'>https://login.microsoftonline.com/extSTS.srf</a:To> ' +
 '<o:Security ' +
 's:mustUnderstand='1' ' +
 'xmlns:o='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'> ' +
 '<o:UsernameToken> ' +
 '<o:Username>' + username + '</o:Username>' +
 '<o:Password>' + password + '</o:Password>' +
 '</o:UsernameToken>' +
 '</o:Security>' +
 '</s:Header>' +
 '<s:Body>' +
 '<t:RequestSecurityToken xmlns_t='http://schemas.xmlsoap.org/ws/2005/02/trust'> ' +
 '<wsp:AppliesTo xmlns_wsp='http://schemas.xmlsoap.org/ws/2004/09/policy'> ' +
 '<a:EndpointReference> ' +
 ' <a:Address>' + host + '</a:Address> ' +
 '</a:EndpointReference> ' +
 '</wsp:AppliesTo> ' +
 ' <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType> ' +
 '<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> ' +
 ' <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType> ' +
 '</t:RequestSecurityToken> ' +
 ' </s:Body> ' +
 '</s:Envelope>';

HttpRequest reqBinaryToken = new HttpRequest();
reqBinaryToken.setEndpoint(‘https://login.microsoftonline.com/extSTS.srf’);
reqBinaryToken.setMethod(‘POST’);
reqBinaryToken.setbody(tokenRequestXml);
reqBinaryToken.setHeader(‘Content-Length’,String.valueof(tokenRequestXml.length()));
reqBinaryToken.setTimeout(60000);

HttpResponse responseBinaryToken = new HttpResponse();
Http httpBinaryToken = new Http();
responseBinaryToken = httpBinaryToken.send(reqBinaryToken);
string xmlContent = responseBinaryToken.getBody();
Dom.Document doc = responseBinaryToken.getBodyDocument();
Dom.XMLNode address = doc.getRootElement();
//XmlStreamReader reader = new XmlStreamReader(responseBinaryToken.getBody());
string outxmlstring = String.valueof(doc.getRootElement().getName());//gives you root element Name

XmlStreamReader reader = new XmlStreamReader(responseBinaryToken.getBody());
while(reader.hasNext()) {
if (reader.getEventType() == XmlTag.START_ELEMENT && reader.getLocalName()== ‘BinarySecurityToken’) {
reader.next();
if(reader.hasNext()){
if(reader.getEventType() == XmlTag.CHARACTERS){
token = reader.getText();
token += ‘&p=’;
}
}
}
reader.next();
}

HttpRequest requestCookie = new HttpRequest();
requestCookie.setEndpoint(‘https://yourdoamin.sharepointonline.com/_forms/default.aspx?wa=wsignin1.0’);
requestCookie.setHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);
requestCookie.setHeader(‘User-Agent’,’Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)’);
requestCookie.setMethod(‘POST’);
requestCookie.setBody(token);
requestCookie.setHeader(‘Content-Length’,String.valueof(token.length()));

HttpResponse responseCookie = new HttpResponse();
Http httpCookie = new Http();
responseCookie = httpCookie.send(requestCookie);
string location = responseCookie.getHeader(‘Location’);

if(responseCookie.getStatus() == ‘MovedPermanently’){
HttpRequest reqMovedPermanently = new HttpRequest();
reqMovedPermanently.setHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);
reqMovedPermanently.setMethod(‘POST’);
reqMovedPermanently.setEndpoint(‘https://yourdoamin.sharepointonline.com/_forms/default.aspx?wa=wsignin1.0’);
reqMovedPermanently.setBody(token);
reqMovedPermanently.setHeader(‘Content-Length’,String.valueof(token.length()));
reqMovedPermanently.setHeader(‘Location’, location);
reqMovedPermanently.setHeader(‘User-Agent’,’Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)’);
HttpResponse responseMovedPermanently = new HttpResponse();
Http httpMovedPermanently = new Http();
responseMovedPermanently = httpMovedPermanently.send(reqMovedPermanently);
cookie = responseMovedPermanently.getHeader(‘Set-Cookie’);
}
else
{
cookie = responseCookie.getHeader(‘Set-Cookie’);
}

HttpRequest requestDigest = new HttpRequest();
requestDigest.setEndpoint(‘https://yourdoamin.sharepointonline.com/_api/contextinfo’);
requestDigest.setMethod(‘POST’);
requestDigest.setBody(body);
requestDigest.setHeader(‘Content-Length’,String.valueof(body.length()));
requestDigest.setHeader(‘Accept’,’application/json;odata=verbose’);
requestDigest.setHeader(‘Content-Type’,’application/json;odata=verbose’);
requestDigest.setHeader(‘Cookie’,cookie);

Http httpRequestDigest = new Http();
HttpResponse responseRequestDigest = new HttpResponse();
responseRequestDigest = httpRequestDigest.send(requestDigest);
string requestDigestValue = responseRequestDigest.toString();
string xmlContentRequestDigest = responseRequestDigest.getBody();

Integer index1 = xmlContentRequestDigest.indexOf(‘”FormDigestValue”:”‘);

Integer index2 = ‘”FormDigestValue”:”‘.length();

string contentRequestDigest = xmlContentRequestDigest.Substring(index1 + index2);

string requestDigestXml = contentRequestDigest.split(‘”‘)[0];

HttpRequest reqWrite = new HttpRequest();
HttpResponse resWrite = new HttpResponse();
Http httpWrite = new Http();
reqWrite.setEndpoint(‘https://yourdoamin.sharepointonline.com/_api/web/lists/GetByTitle(‘AccountTest’)/items’);
reqWrite.setMethod(‘POST’);
reqWrite.setCompressed(false);
reqWrite.setHeader(‘Accept’

Partner with us to ensure seamless collaboration and communication across the enterprise with SharePoint.

SharePoint 2013 User Profile Synchronization with Active Directory

SharePoint active directory import allows you to import the active directory user information to SharePoint user profile service.

User profile service application stores the information about the user like first Name, last name, Phone Number, location etc. in central location. SharePoint will create three databases for storing the profile information and associated data.

  1. Profile Database – This particular DB stores the user profile information.
  2. Social tagging Database – This database stores social tags and notes created by users.
  3. Synchronization Database – This database stores configuration and staging information. This helps for synchronizing data from external sources such as the Active Directory Domain Services (ADDS).

Prerequisites to perform the import for Sharepoint synchronization:

  • To perform the synchronization, you must be a member of farm administrator group.
  • You must know the credentials of domain controller that has synchronization permission.

Before you begin with the synchronization note what AD import does not support.

  • Import operation is one way, changes made to the SharePoint user profiles wont reflect in AD.
  • The active directory import option lets you configure and use only a single farm wide property mapping.
  • Active directory import option does not support generic (non-AD) LDAP sources.
  • Active directory import option does not support BCS Import.

Importing the User profile information to active directory involves following four steps.

  • Enable Active directory import.
  • Configure synchronization connection.
  • Map active directory attributes with user profile properties in SharePoint.
  • After completion of above three start synchronization in SharePoint.

Enable Active directory import:

  • Open SharePoint Central Administration click on Manage service application under the Application Management section.
  • In Manage Service Applications page, click on User Profile Service Application.
  • In Manage Profile Service page click Configure Synchronization Settings in the Synchronization section.
  • On the Configure Synchronization Settings page select Use SharePoint Active Directory Import option, and click OK.

Configure synchronization connection:

  • On the Manage Profile Service page, click Configure Synchronization Connections.
  • Now click on Create New Connection button.
  • In new synchronization connection page, enter the connection name in the Connection Name text box.
  • From the Type list, select Active Directory Import.
  • In the Fully Qualified Domain Name box, enter the Fully Qualified Domain Name.
  • Select the authentication provider type in Authentication Provider Type box.
  • Select an Authentication provider from the Authentication Provider Instance box when you select Trusted Claims Provider Authentication or Forms Authentication. The Authentication Provider Instance box lists only the authentication providers that are currently used by a Web application.
  • In the Account name box, enter the synchronization account with domain and username. The synchronization account must have Replicate Directory permissions or higher in the root OU of Active Directory.
  • In the Password box, enter the password for the synchronization account.
  • Enter the password for the synchronization account again in the Confirm password box.
  • In the Port box, enter the connection port. (optional)
  • Select Use SSL-secured connection If a Secure Sockets Layer (SSL) connection is required to connect to the directory service. (optional)
  • You can also filter objects that are imported from the directory service, in the Filter in LDAP syntax for Active Directory Import box, enter a standard LDAP query expression to define the filter. (optional)
  • In the Containers section, click Populate Containers and then select the containers from the directory service which you want to synchronize. All OUs selected will be synchronized along with their child OUs.
  • Click OK and a newly created connection will be listed on the Synchronization Connections page.

Map AD attributes with user profile properties.

  • Click Manage service applications in the Application management section in the Central Administration.
  • Click User Profile Service Application in service application page.
  • Click Manage User Properties in the People section.
  • Right-click the name of the property that you want to map a directory service attribute, and then click Edit.
  • You can also remove an existing mapping by selecting the mapping that you want to remove, and then click Remove in the Property Mapping for Synchronization section.
  • To add a new mapping: In the Add New Mapping section, in the Source Data Connection list, select the data connection that represents the directory service to which you want to map the user profile property to.
  • In the Attribute box, enter the name of the directory service attribute to which you want to map the property.
  • Click Add.
  • Click OK.
  • Repeat steps 4 through 7 to map additional properties.

Start synchronization:

  • Click Manage service applications in the Application management section in the Central Administration.
  • Click on Start Profile Synchronization in the Synchronization section.
  • Select Start Full Synchronization in Start Profile Synchronization, if this is the first time you are synchronizing or if you have already added or modified any synchronization connections in the past.
  • Select Start Incremental Synchronization to synchronize only information that has changed in the last time synchronization.
  • Click OK. The Manage Profile page will display the status of profile synchronization in the right panel.

Need help with Sharepoint. Reach out to our experts to help you with a full range of well-structured services for planning, developing, and deploying SharePoint based solutions.