One of the bits of ServiceNow development I have found the most challenging is dealing with Credentials and Aliases, specifically those for OAuth2. More then one session of Live Coding Happy Hour ended in failure specifically because of my inability to grasp a) what was happening at all in the OAuth and Credentials data model and b) where I should be looking for any specific piece of the puzzle. Compound that by the fact that our prime use of this is in our YouTube spoke where we wanted to have something in the scope and the spoke by default but I wasn’t exactly sure what that should be . It all adds up to a mess.
I will freely admit that in previous eras, I leaned heavily on Josh Nerius as a reference. Because he was good at this stuff, I was able to avoid the painful hard work of figuring it out. Losing that luxury recently, I was forced to drop into credential world and stay there until I fought my way out. At this point, I feel like I finally have the flight time to blog about this post. (I was scheduled to write it weeks ago and felt like I couldn’t.)
We had a long struggle first getting any OAuth authorization working properly. Then we did get the authorization flow but were getting an Access Token, which is one that expires every hour. Considering this application is one that integrates to YouTube for us, requiring the user to re-authorize via OAuth every hour was not workable so we had to figure out then how to convert the (barely) working OAuth flow to use Refresh Tokens that automatically fetch new Access Tokens.
To start off with, I am going to try my hand at a diagram to explain the basics of the data model. I found it quite confusing that I wanted our YouTube Spoke to have OAuth authentication but the thing you actually add is many steps from that. Here is my attempt at explaining the model. The orange boxes are those related to Connections or Credentials generally, the blue ones are those that specifically deal with OAUth.
To start with, at the top level when we wanted to make our connection to the YouTube Data API (slight misnomer, this is to schedule live streams) we needed to add a Connection and Credential Alias. This record has a reference to a Credential and to a Connection. At this point, it is more of a pointer to other resources. This record lives in the scope of the YouTube Spoke.
The Connection itself is one step closer to the actual act of authenticating. This record has a reference to a Credential and to a Connection. At this point, it is more of a pointer to other resources. It still is not in itself a solution but we are honing in on it. This record lives in the scope of the YouTube Spoke.
The Credential record is now where we actually begin to enter the world of OAuth. It can be of many types and when you create one, you’ll see an interceptor that allows you to choose. For this application we wanted OAuth 2.0 Credentials.
The Credential is the record that can be considered the triggering or owning record of the OAuth transaction. You’ll note that it is the one that has a related link to fetch the OAuth Token. However, there is not visible on this record the actual tokens which can be confusing. This is the one that contains the reference to which OAuth Entity Profile will be used to fetch the token.
The OAuth Entity Profile contains a reference to an OAuth Provider record. It is where you define the grant type of the OAuth transaction and also where you list the scopes that will be requested by this transaction. When you successfully get tokens but not access to the desired resources, this is the place to begin. This lives in the scope of the YouTube Spoke.
The OAuth Provider record gets tricky, because it actually is an Application Registry record. You’ll see that this is where the serious configuration begins. The client ID and client secret are defined here. The URLs needed to define the flow are configured here: authorization URL, token URL, token revocation URL and the redirect URL after a successful authentication. The default grant type is configured here, as well as the very important refresh token lifespan parameter. Lastly, this record contains a reference to an OAuth API Script record. This may be important for your OAuth flow to work. It certainly was for the YouTube Data API.
The OAuth API Script record points to a Script Include. In this, you need to define some callback functions that the OAuth processor will call as it works. There does not have to be any logic in them but they do need to exist. There are two important bits of our specific script. One is in preprocessAuthToken that adds a single name/value pair to the parameters being requested, “access_type” equal to “offline”. This is specifically for Google’s implementation of OAuth. The other is in postprocessAccessToken, which takes the JSON payload of the token response and parses it out and puts it back in the parameters of the accessTokenResponse. This is also Google, and other OAuth providers will need other code here to deal with their eccentricities.
You’ll see through all this we had no direct reference to the actual tokens fetched by any of these processes. They do exist but are not directly linked in any related lists by default. Under System OAuth -> Manage Tokens in the application navigator, you will find the list of tokens on your system. This was how we figured out originally that we were correctly fetching Access Tokens but not getting Refresh Tokens. If you are debugging your own OAuth Token flow, you will need to look here to see what tokens you have actually fetched and when.
This is a complicated process that is not always obvious where you need to be looking. Hopefully this helps with the mental model of how the various pieces of the ServiceNow records interact to ultimately end up with an OAuth Access Token with the correct authorizations and a usable time frame for your application. There will be more about this topic in the future as it is a perennial topic for developers. OAuth is tricky in any case and ServiceNow has its own complications in sending and receiving the transactions.
This example is specifically about fetching the Refresh Token from Google. Unfortunately, these mechanisms are not standardized and can vary significantly from provider to provider. In the near future, we will feature another post describing some of the strategies for fetching the tokens from a variety of the most commonly used providers.
Good luck and happy token fetching!