Online Development - What API to Use?

Ratings
When partners build an online application, or a one-off integration, the first question I usually get is “what API’s are available?”.

I generally respond with we support both SOAP and REST web services. And then their follow-up question is generally “which API should I use?”. The answer is, well it depends.

Our REST and SOAP API’s have different authentication and data access techniques, and which one you chose really depends on the type of integration you are building. This article highlights some of the differences of each, with respect to SuperOffice, and aims to clarify which API you should use.

API Comparison

Before continuing, let me just state that I am well-aware that comparing REST and SOAP can be like comparing apples to oranges, but it is the most common way people [in general] discuss web service API’s.

SOAP is historically known to be a robust enterprise-ready option for performing remote invocations using XML. It’s verbosity, however, carries a heavy toll on network traffic and lost it’s commercial appeal in recent years.

REST is best known for building fast responsive JSON-based online applications. While REST supports XML exchanges, RESTful API’s normally send JavaScript Object Notation (JSON) data which is more light-weight and therefore faster.

With REST, API consumers simply use URLs to access SuperOffice resources and exchange JSON data.

With SOAP, API consumers commonly use proxies that simplify sending XML back and forth across the wire. People either generate their own proxies or optionally use proxies provided by SuperOffice.

Historically, SuperOffice proxies were included in the SDK, but are now available for download on nuget.

Both SOAP proxy options, self-generated proxies and SuperOffice proxies, have a different authentication, authorization and session-handling experience.

Self-generated proxies must create and manage user sessions themselves, as well as decide how to store and populate required details sent in each SuperOffice web service invocation.

SuperOffice proxies are easier in that they manage the details for you. The power, however, does require API consumers to know more about SuperOffice NetServer internals - specifically three plugin classes that help manage session
state.

OnlineAuthentication.png

Thankfully these are shared on github, as with example applications that demonstrate how they are used.

Authentication Scenarios

Prerequisite

Prior to authentication, regardless if it is interactive (user) or non-interactive (server-to-server) authentication, an application must be granted access to a tenants web service endpoints.

Granting an application access rights is also referred to as consent or authorization.

An application is granted access to a tenants web services under the following scenarios:

  1. A tenant administrator installs the app via the app store.
  2. A developer writing the app mocks the installation of the application.

Both require a user to open a browser and navigate to the following url:

OLD Form:
http://{env}.superoffice.com/login/?app_id=YOUR_APP_ID

OAuth 2.0 Form:
https://{env}.superoffice.com/login/common/oauth/authorize?response_type=id_token token
&client_id=YOUR-APP-ID&redirect_uri=YOUR-REDIRECT-URL&scope=openid&state=12345
&nonce=7362CAEA-9CA5-4B43-9BA3-34D7C303EBA7

The difference of use between OLD FORM and OAuth2 URLs is the HTTP Response sent to the Redirect URL.

The OLD URL request receives a JWT or SAML token in the body of the response with claims, including a Ticket credential.

The OAuth2 URL request, which is an Implicit Flow request, returns a URL fragment containing an JWT id_token, with tenant and user claims, plus an access_token credential. See the SuperOffice OpenID Connect article for more details.

For an app listed in the app store, this url is usually what lies behind the Install button. For developers creating an app locally on their dev-machine, they must manually invoke this url in a browser to initiate [mock] an installation.

Both scenarios navigate to the SuperOffice SuperID login page, where either a tenant administrator or developer acting like a tenant administrator provides credentials and gives consent to the application.

When an application is registered, they also provide a redirect url, which is where SuperID redirects the user once authentication and consent is given.

The redirect is a POST request that contains a JSON Web Token (JWT) in the request body.

While the old form and new OAuth 2.0 form have a different sequence of events that lead to the response that contains the JWT security token, the JWT contains the claims necessary to interact with the tenant. For provisioning an application dependencies, such as: navigator buttons, web panels, list items, etc. The claims include URLS for both REST and SOAP web service endpoints, and the almighty SystemUserToken - for non-interactive (server-to-server) communications.

As for web service access, or authorization , when using the old form, then the claims also contain the administrators Ticket credential. When using the OAuth 2.0 flow, in addition to the JWT token, the access_token is included in the response.

Older online applications that use the old form were not required to include the redirect_url. It was optional. Application that needed to override the default redirect_url could supply a redirect_url as long as it was registered in the applications redirect_url whitelist. If an application supplies a redirect_url that does not exist in the white list, SuperID will simply redirect the users online tenant.

http://sod.superoffice.com/login/?app_id=YOUR_APP_ID&redirect_url=YOUR_WHITELISTED_REDIRECT_URL

There is no way to circumvent in the installation and consent process… An application must receive consent in order to access a tenants resources! Any attempt to authenticate via the API’s without prior consent will fail.

Interactive and Non-Interactive Authentication

First and foremost, regardless whether an application uses the SOAP or REST APIs, no application is allowed to present users with their own sign-in screen. All interactive authentications must be performed via the SuperOffice Online sign-in page. All normal users must be sent to the same URL as when their administrator installs the application.

Therefore the results of an interactive authentication for a normal user is very much the same as their administrator or developer when the application was installed.

Once authenticated, the interactive user is redirected to the applications redirect_url and the application can provision anything necessary for that user, and/or redirect the user back to SuperOffice.

It’s not uncommon for users to interactively sign-in to an app when it is exposed in SuperOffice through a web panel. In that case, and when using OAuth 2.0, include the <uctx> template variable in the web panel URL to get the customers context identifier and include that in the endpoint.

https://sod.superoffice.com/login/{contextIdentifier}/oauth/authorize?...

// example

https://sod.superoffice.com/login/Cust12345/oauth/authorize?response_type=id_token token
&client_id=YOUR-APP-ID&redirect_uri=YOUR-REDIRECT-URL&scope=openid&state=12345
&nonce=7362CAEA-9CA5-4B43-9BA3-34D7C303EBA7

This will ensure the web panel application provides the user with seamless SSO experience.

Normal users are every-day users employed by the company that license SuperOffice, and use it to help accomplish their daily goals. System users are special accounts that have unlimited access to SuperOffice data, and are used to perform routine tasks that are not owned by normal users. System accounts used through web services do not support impersonation contexts, so they cannot do work on behalf of a normal user.

OpenID Connect, which is popular identity layer built on top of OAuth 2.0, is commonly used by RESTful API consumers and is supported in SuperOffice Online.

Most people who chose to use OpenID Connect, use one of the available OpenID Connect frameworks provided depending on their technology stack.

While nearly impossible to cover homegrown solutions, SuperOffice has successfully tested OpenID Connect friendly frameworks; including Microsoft ASPNET authentication services, as well as Identity Server’s oidc-client. In fact, the SuperOffice Online Angular example uses the oidc-client-js npm package.

SuperOffice supports interactive OpenID Connect workflows, such as Authorization Code, Implicit and Hybrid Flow, but there is no support for non-interactive OAuth2 workflows; such as Client Credentials.

SuperOffice does, however, issue refresh_token‘s, and in that way does support a non-interactive flow once the user has interactively signed in. Since it does require the user to first interactively authenticate to receive a refresh_token, we refer to this as Semi-Interactive. From that point on, each users’ refresh token can be securely stored and use toward the tokens endpoint to obtain an access_token, which is then used as a credential to perform api calls on behalf of a particular user.

Supported Scenarios

Requirement SOAP REST Comments
User-Interactive X X Default workflow.
Non-Interactive X   System-user workflow.
Semi-Interactive X X Refresh_token workflow.

Interactive Scenario

Interactive authentication is facilitated by the SuperOffice Online sign-in page. There really isn’t much more that can be said here that hasn’t already been discussed in the Authentication section above.

Non-Interactive Scenario

In order to conduct true background processing, applications must use the system user token that was issued to them during the installation process. Applications use the SOAP-based PartnerSystemUserService endpoint to exchange a system user token for a system-user ticket.

When used in a SOAP request, the system-user ticket is used as credentials, placed inside each SOAP header as seen in the ContactAgent.GetContactEntity method.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope namespaces left out for brevity>
  <Contact:ApplicationToken>1234567-1234-9876</Contact:ApplicationToken>
  <Contact:Credentials>
    <Contact:Ticket>7T:1234abcxyzExample==</Contact:Ticket>
  </Contact:Credentials>
 <SOAP-ENV:Body>
   <Contact:GetContactEntity>
    <Contact:ContactEntityId xsi:type="xsd:int">0</Contact:ContactEntityId>
   </Contact:GetContactEntity>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

When used in a REST request, the system-user ticket is placed in the Authorization header as an SOTICKET.

Authorization: SOTicket 7T:1234abcxyzExample==
SO-AppToken: Application_Token_Value

System users have unlimited access to the database and are not subject to any security or sentry constrains. System users cannot impersonate other users in the online environment.

Semi-Interactive Scenario

Applications that use OAuth2/OpenID Connect to authenticate users via the Authorization Code Flow, or Native App Flow, do receive a refresh token. The refresh token is (as of this writing) good for as long as the user is authorized to access the application, and can be securely stored on behalf of that user for subsequent API interaction.

To use a refresh token, the application must issue a POST request to the tokens endpoint with the following details:

  1. client id
  2. cient
  3. redirect_uri
  4. grant_type specified as refresh_token
  5. the actual refresh token

An example POST request:

POST Request (can be tested in a client such as Postman or Fiddler)
Content-Type: application/x-www-form-urlencoded

https://sod.superoffice.com/login/common/oauth/tokens?
client_id=f123b7d98f3c496fb5aaa4b1f54cawe6&
client_secret=09d5f3bdf0afbc3bv9d0682e9b86lk89&
redirect_uri=http://partner-app/callback&
grant_type=refresh_token&
refresh_token=t6XaHSHkTbB1234abcxyzExample

The response contains the access_token necessary to issue in subsequent REST or SOAP requests.

When used in RESTful requests, the access_token is placed in each request Authorization header using the Bearer prefix.

Accept: application/json
Authorization: Bearer 8A:Cust12345.abcxyzExample==

Supported in version Services86 and higher, when used in SOAP requests, the access_token is placed in each SOAP header.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope namespaces left out for brevity>
  <Contact:ApplicationToken>1234567-1234-9876</Contact:ApplicationToken>
  <Contact:Credentials>
    <Contact:Ticket>8A:Cust12345.abcxyzExample==</Contact:Ticket>
  </Contact:Credentials>
 <SOAP-ENV:Body>
   <Contact:GetContactEntity>
    <Contact:ContactEntityId xsi:type="xsd:int">0</Contact:ContactEntityId>
   </Contact:GetContactEntity>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Conclusion

There are a lot of integration options, and I can understand if it’s been a head-scratching time trying to understand where to begin. At the very least I hope this article has clarified some of the confusion, and brought you much closer to successfully understanding what the options are and which API is the right fit for you.

Post Comment To the top