Technologies

Java-service integration with SharePoint Online via REST API

author
Marketing Team
WaveAccess
Published June 23, 2015
Let us tell you more about our projects
Start here

Sharing our experience on using REST API solution to implement a mechanism of data manipulation in SharePoint Online.

It is often a challenge to optimize the work that is performed with the various repositories (sets of  the same types of data) during the development of enterprise information management systems (IMS), as the interaction with them causes the filling and editing of numerous forms. Design, planning, and development of such forms may take a few weeks, and it delays the start of systems operation.

Solutions like SharePoint Online help to launch subsystem of registers maintenance rapidly. They provide not only functionality for forms building and storing the data in different formats but also the possibility of access differentiation and integration, and much more. Developers need only to implement a mechanism of data manipulation in SharePoint. At WaveAccess, we used REST API solution for such implementation.

Authentication

As SharePoint Online has strict safety standards, authentication for working with REST API consists of three steps:

  1. Get the security token from Microsoft authentication portal:

            
              public String receiveSecurityToken() throws TransformerException, URISyntaxException {
              RequestEntity<String> requestEntity = new RequestEntity<>(buildSecurityTokenRequestEnvelope(), HttpMethod.POST, new URI("https://login.microsoftonline.com/extSTS.srf"));
              ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
              DOMResult result = new DOMResult();
              Transformer transformer = TransformerFactory.newInstance().newTransformer();
              transformer.transform(new StringSource(responseEntity.getBody()), result);
              Document definitionDocument = (Document) result.getNode();
              String securityToken = xPathExpression.evaluateAsString(definitionDocument);
              if (StringUtils.isBlank(securityToken)) {
                throw new SharePointAuthenticationException("Unable to authenticate: empty token");
              }
              return securityToken;
              }
            
          

    The envelope that is sent to the portal has the following format:

            
              <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
              <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>[SharePoint domain address]</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>
            
          
  2. Get the cookies from the SharePoint Online server:

            
              public List<String> getSignInCookies(String securityToken) throws TransformerException, URISyntaxException {
              RequestEntity<String> requestEntity = new RequestEntity<>(securityToken, HttpMethod.POST, new URI("[SharePoint domain address]/_forms/default.aspx?wa=wsignin1.0"));
              ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
              HttpHeaders headers = responseEntity.getHeaders();
              List<String> cookies = headers.get("Set-Cookie");
              if (CollectionUtils.isEmpty(cookies)) {
                throw new SharePointSignInException("Unable to sign in: no cookies returned in response");
              }
              return cookies;
              }
            
          
  3. Get the signature for requests to the SharePoint Online server:

            
              public String getFormDigestValue(List<String> cookies) throws IOException, URISyntaxException, TransformerException, JSONException {
              MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
              headers.add("Cookie", Joiner.on(';').join(cookies));
              headers.add("Accept", "application/json;odata=verbose");
              headers.add("X-ClientService-ClientTag", "SDK-JAVA");
              RequestEntity<String> requestEntity = new RequestEntity<>(headers, HttpMethod.POST, new URI("[SharePoint domain address]/_api/contextinfo"));
              ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
              JSONObject json = new JSONObject(responseEntity.getBody());
              return json.getJSONObject("d").getJSONObject("GetContextWebInformation").getString("FormDigestValue");
              }
            
          
Running queries to the SharePoint Online server

Now we have everything that is needed to run queries to the SharePoint Online server. In the request headers, you must add the received cookies, put the required Content-Type and add a signature. Generally, the method looks like this:

        
        public String performHttpRequest(String path, String json, boolean isUpdate) throws Exception {
          String securityToken = service.receiveSecurityToken();
          List<String> cookies = service.getSignInCookies(securityToken);
          String formDigestValue = service.getFormDigestValue(cookies);
          MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
          headers.add("Cookie", Joiner.on(';').join(cookies));
          headers.add("Content-type", "application/json;odata=verbose");
          headers.add("X-RequestDigest", formDigestValue);
          if (isUpdate) {
            headers.add("X-HTTP-Method", "MERGE");
            headers.add("IF-MATCH", "*");
          }
          RequestEntity<String> requestEntity = new RequestEntity<>(json, headers, HttpMethod.POST, new URI(path));
          ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
          return responseEntity.getBody();
        }
        
      

It should be noted that the security token has an expiration time - one day. So this makes it possible to optimize the performance of the service using cache.

Conclusion

Even despite the restrictions and difficulties of integration, SharePoint Online provides many useful features and completed environment. This helps to reduce the time costs of launching such projects which require the processing of large amount of forms.

If in the current project you need to integrate Java-service with SharePoint Online via REST API, or to develop a corporate management information system, e-mail us at hello@wave-access.com

Energy Management System for Mata Energy

The solution is aimed to facilitate sector-coupled energy supply, improving its efficiency. For the client we provided a consulting session, and developed an MVP.

Association technology modernization without a full rebuild

Associations want to be a career-long partner to their members, but the technology underneath often works against that. A practical route to modernization: improve the systems already in place instead of adding another platform.

ETL solution for an automotive data platform

Discover how an international business automation company enhanced the performance and scalability of its automotive data analytics platform by migrating from a local database to secure cloud environment. This ETL project streamlined data operations and laid the foundation for long-term growth.
What do AI Agents really mean for the travel business in practice? From costs and ROI to privacy and implementation, human roles, and what lies ahead, here are the crucial questions leaders are asking today.
WaveAccess has become an integration partner of Keboola, a cloud-based data management platform that helps organizations automate and scale their data operations. Together, we will enable faster, smarter and more efficient data implementation across industries.
Behind every seamless travel experience is a quiet enabler: system integration. As the industry pushes toward hyper-personalization, real-time responsiveness, and scalable digital operations, it's the integration of fragmented systems that makes true innovation possible. Let's break down why system integration and data migration remain Travel’s biggest challenges, and how to solve them.

Related Services

SharePoint Development
Software Engineering SharePoint Development
Application Development
Software Engineering Software Engineering
SharePoint Portal Development
Software Engineering SharePoint Development

How we process your personal data

When you submit the completed form, your personal data will be processed by WaveAccess USA. Due to our international presence, your data may be transferred and processed outside the country where you reside or are located. You have the right to withdraw your consent at any time.
Please read our Privacy Policy for more information.