Understanding APIs: SOAP

In my previous post, I talked about the basics of REST (representable state transfer) APIs (application programming interfaces). If you haven’t read it yet, I highly recommend you read that post before continuing.

In this post, we will be talking about the basics of simple object access protocol (SOAP) APIs, and we will primarily focus on a real SOAP service: Microsoft Exchange Web Services. RESTful APIs, which are the most commonly used APIs today, are powerful and provide a simple way to interact with a service or application via an exposed interface. Even though REST is the most popular, SOAP is still used today by many major services.

REST-based APIs are strictly HTTP requests with some of them requiring additional content for authorization as well as body content. SOAP-based APIs are HTTP requests as well, but when you use SOAP APIs, you must POST a defined XML document in the body of the request as well as other attributes.

Authentication

SOAP APIs will typically require authentication, but that authentication is typically in the form of a username and password. Authentication for SOAP-based APIs can be considered a basic form of authentication whereas REST APIs usually have a more robust authentication mechanisms.

There are other methods when it comes to authentication using a SOAP API. If the SOAP service uses WS-Security, then you can also authenticate using “various security token formats, such as Security Assertion Markup Language (SAML), Kerberos, and X.509.”

Early this year, Microsoft Exchange Web Services added the capability to authenticate to EWS using the OAuth2 standard as a form of authentication. I highly recommend that you use this method when authentication an application or service to EWS.

In addition to these standards, authenticating with SOAP APIs will either require a pre-authorization token, or it will require that you authenticate every time you use the API.

Methods

SOAP APIs will always require you to provide body content in requests made. But SOAP APIs differ quite a bit from REST APIs. Fun fact, REST does not have an RFC standard but SOAP does.

SOAP APIs are XML-based. SOAP-based APIs require that you POST content when requesting data from the API. In comparison to REST APIs—no matter if the intended action is to GET, POST, PUT, DELTE, etc. data to an API endpoint—you will always use a POST method. Additionally, each POST request requires that you provide an XML document in the body of your request.

SOAP APIs have a web service detection language (WSDL) that outlines the functionality of a SOAP service. This WSDL can be quite large and extremely complex, but hopefully the creators of the SOAP API have thorough documentation available so you do not have to decipher the service.

The best way to explain SOAP APIs is to look at a real life example. Let’s take a look at a common service that uses SOAP: Microsoft Exchange and/or Office 365.

Microsoft Exchange on-premises and Office 365 both have—and currently support—a SOAP API called EWS (Exchange Web Services). There are rumors that Microsoft is planning on removing this from future versions of Exchange, but I personally do not think this will happen for a long while (backwards compatibility being the number one reason).

In Office 365, you can access EWS by visiting the following URL and authenticating with your username and password: https://outlook.office365.com/autodiscover/Services.wsdl.

This is actually not the direct link, this is accessing EWS using Microsoft’s Autodiscover service, but this should allow you to view the WSDL in your browser once you have authenticated using Office 365 credentials. Autodiscover is a mechanism used by EWS to assist with identifying and connecting to the appropriate exchange server based on a prescribed methodology. Here is the direct link: https://outlook.office365.com/ews/services.wsdl.

As you can see this WSDL file immediately looks complex, and that’s because it is. This defines every dependency and all actions that can be performed by the user’s credentials you provided. Luckily for us, Microsoft provides really good documentation for EWS. The point of showing you this is that SOAP can be quite large, but it is surprisingly efficient and powerful.

To provide more context, let’s look at the XML for a SOAP request to resolve a username within our Office 365/Exchange tenant:

Breaking down each attribute in this SOAP request could take quite a bit of time, but the basics include an envelope, header and body, which make up our XML body content.

The envelope of this document defines our namespaces (XML namespaces are denoted by xmlns). A namespace typically includes the version of XML being used, as well as the location (URL) for other terms or variables used within this document. The structure of an attribute within our namespace looks like this:

xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover" 
xmlns:{prefix}={URL to definition of namespace}

These terms can be defined in the envelope or directly as an attribute in a tag within the body section. For example, in the body section, we see the element ResolveNames, and it contains a couple namespace attributes which specify the definition for its messages and types. You can see this here:

<ResolveNames 
xmlns=""http://schema.microsoft.com/exchange/services/2006/messages"" xmlns:t=""http://schemas.microsoft.com/exhcnage/services/2006/types"" returnfullcontactdata=""true""> </resolvenames>

These messages and types are definitions that you can also see within this SOAP service. You can view these in your browser by going to these two links:

A SOAP XML header may also be required. If it is, then it may require that you specify the version of the service you are using plus any additional attributes. With Exchange EWS, you must specify a compatible version of Exchange you are using. The current available options are listed here, but they are mapped to the actual version number of your Exchange:

  • Exchange2007
  • Exchange2007_SP1
  • Exchange2010
  • Exchange2010_SP1
  • Exchange2010_SP2
  • Exchange2013
  • Exchange2016
  • Exchange2019

The Body of your XML document contains the methods and elements you are wanting to perform. A method in this case can be used to retrieve information from the API or to post data, but this is only defined within our XML body, since we will always POST this to our SOAP service. An element may be an attribute you must specify with the request or some setting. Again this will be defined by the SOAP service.

This is well documented for Exchange, but some other services may not be. If you are just learning SOAP APIs, then I strongly recommend that you stick with a service that is well documented.

As I mentioned previously, every SOAP request starts with a POST HTTP request with a body attribute that contains XML similar to this. Here is an example (without authentication logic) of sending this type of request to EWS using Python:

import requests
soap_body = '" 
<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover" 
xmlns:wsa="http://www.w3.org/2005/08/addressing" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<soap:Header> 
<a:RequestedServerVersion>Exchange2016</a:RequestedSerVerversion> 
<wsa:Action>http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/ResolveNames</wsa:action> 
</soap:Header> 
<soap:Body>
<ResolveNames 
xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" 
ReturnFullContactData="true"> 
<UnresolvedEntry>first.last@swimlane.com</UnresolvedEntry>
</ResolveNames>
</soap:Body>
</soap:Envelope>
 '"
response = requests.post( 
url='https://outlook.office365.com/EWS/Exchange.asmx', 
data=soap_body, 
headers={'content-type': 'text/xml; charset=UTF-8'}, 
auth=('first.last@swimlane.com','password'), 
verify=False 
)

Once you have made a POST request to a SOAP API, the API will send a response back that you will need to parse to retrieve your response. This will also provide additional context into whether or not your request had errors.

I hope this helps you understand the differences between both REST and SOAP APIs. Each have their unique takes on retrieving and interacting with services, but either way, Swimlane supports and can utilize any API to orchestrate business processes—no matter if it is for security or another department within your organization.


*** This is a Security Bloggers Network syndicated blog from Swimlane authored by Josh Rickard. Read the original post at: https://swimlane.com/blog/understanding-apis-soap/