- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 12-30-2018 01:51 AM
One of the most commonly used authentication mechanisms when you consume or produce a web service is Basic Authentication. Basic Authentication requires two credentials
- UserID
- Password
If your requirement is to allow a 3rd party application to use OAuth2 authentication to consume service-now's web service, then you will need to setup OAuth credentials in the application registry which include ClientID, Client Secret, Default Grant Type etc. Along with the OAuth specific credentials, you will also need a UserID and Password of a user account (sys_user record) that has access to the resources in ServiceNow.
I ran into this special situation when I created a Scripted Rested API to allow a 3rd party application to consume my Web Service. The 3rd party application was using OAuth2 Authentication, obviously I used credentials like Client Secret and ClientID and, the UserID and Password of my User Account which has access to read/write to one of my tables. Everything was developed and the integration was working perfect.
After few days I have seen some questions in the community which pointed out that you can still make API calls by using Basic Authentication and bypass OAuth2 authentication. That’s True, may be that’s by design, but the real question is “How to restrict an endpoint in ServiceNow from Basic Authentication?”. The whole point of using OAuth2 is to provide better authentication via access tokens, refresh tokens, client id, secrets and UserID/password of a service account. If somebody gets hold of my UserID and Password of my Service Account, and if they successfully send a request using Basic Auth from a REST client like PostMan or ARC, then the whole point of setting up OAuth Authentication is useless.
If you are in a similar situation, below is the work around.
- Create a system property
- Named: restricted.basic-auth.endpoints
- Type: string
- Value: comma separated list of endpoints you want to restrict from Basic Authentication.
Example screen shot:
- Modify the OOB Script include named BasicAuth
- Modifying an OOB Script include is not recommended, if possible De-Activate the existing OOB Script include and create a new one with the same name.
- Below is Script for the script include [Added a function named isrestricted and this function will be called in another function named getAuthorized to check if the endpoint in the request is restricted for Basic Authentication or not]
var BasicAuth = Class.create(); BasicAuth.prototype = { initialize : function(request, response, auth_type, auth_value) { this.request = request; this.response = response; this.auth_type = auth_type; this.auth_value = auth_value; }, getAuthorized : function() { /* Mechanism to restrict certain endpoints from Basic Authentication */ var checkIfRestricted = this.isrestricted(); if(checkIfRestricted) { return null; } var up = GlideStringUtil.base64Decode(this.auth_value); var split = up.indexOf(":"); if (split == -1) { gs.log("Basic authentication not well formed"); return null; } // locate user and impersonate var userName = up.substring(0, split); var password = up.substring(split + 1); var result = GlideUser.authenticateUser(userName, password); if (!result) { gs.log("Basic authentication failed for user: " + userName); return null; } // user is authenticated, so return it... return result; }, isrestricted : function(){ var endpointsString = gs.getProperty("restricted.basic-auth.endpoints"); var endpointsArray = endpointsString.split(","); var incomingRequestURL = this.request.getRequestURI()+''; if(endpointsArray.indexOf(incomingRequestURL) > -1) return true; else return false; } }
You can scale the above work around to you requirements, but remember : getAuthorized() function in the above script include is used by many other OOB or your custom processes to use Basic Authentication. If you are trying to shape the above work around for your own requirements DO NOT PERFORM GLIDE RECORD OPERATIONS in this script include as it can cause performance impacts. That is the whole reason to use a system property which is lighter than a table read to check for specific endpoints and restrict them from Basic Authentication.
- 6,723 Views

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks for the info Aman. When you mentioned "service account" was that the account used for your Oauth? Did you require oauth for all users on your servicenow instance? I would think if you did that, then basic auth wouldn't work since that holds true when enabling MFA for a user...thanks!

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
One more question - could I use the ACL's for the API's (listed here) to help mitigate who has access? Have you used these before? thanks!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
David,
Below are my answers for your questions
When you mentioned "service account" was that the account used for your Oauth?
Answer: Yes. for OAuth of Grant Type "Password" /"Resource Owner Password Grant" we need to provide UserID and Password (Mostly considered as Service Account)
Did you require oauth for all users on your servicenow instance?
Answer: NO, users logged in normally into the instance by providing their credentials. But for some of the integrations, we had service accounts (a record in sys_user table with necessary roles who need a Non Interactive Session)
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
David,
I used ACL of type REST_Endpoint in the Scripted API resource to check if the User who is trying to Authenticate has appropriate roles or not. (OOB Example you can check is an ACL with Name "Scripted REST External Default")
As an endpoint is subjected to a Non Interactive Session, Defining Read/Write ACL's is not appropriate. So defining ACL's of Operation Execute would do the job as it determines who can execute scripts against a particular table.
Thank you,
Aman Gurram
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Aman,
I am trying to do the same thing. Can you help me understand how to relate the user record to the OAuth credentials created in the application registry ?
If your requirement is to allow a 3rd party application to use OAuth2 authentication to consume service-now's web service, then you will need to setup OAuth credentials in the application registry which include ClientID, Client Secret, Default Grant Type etc. Along with the OAuth specific credentials, you will also need a UserID and Password of a user account (sys_user record) that has access to the resources in ServiceNow.
THanks
quik
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
quiksilver,
There is no direct connection from User Record to OAuth Credentials in Application registry. The USer record should have access to the target resources and make sure Web service access only checkBox is checked.
That should allow your user (service Account) to start a Non-interactive session.
Thank you,
Aman Gurram
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Aman,
Thanks for your reply.
Will this solution work for OOTB Table API or only for Scripted REST API ?
Cheers
Quik
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Quik,
It should also work for OOB Table API's.
Thanks,
Aman
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This is great. Thank you!
Correct me if I'm wrong, but if I set the OOB script include to false and create a new one as above, when I go to upgrade if there were any changes made to the OOB script, it will get marked as SKIPPED... is that correct? I can live with reviewing the changes made to the OOB script during an upgrade if it means that we can enforce Oauth. 🙂
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You are right.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Yes, the record would be marked as skipped - it is changed (the Active field).
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Aman,
How its works for OAuth credentials. How it validate the OAuth users.
Requirement : I have scripted API POST Method its basically authentication with username and password but i am looking for OAuth credentials instead of basic authentication
Could you please help me out.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Aman
I have Scripted Rest API which should be consumed by OAuth only, but the grand type is Client Credentials so no any service account.
How I can solve this?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
For people that come here in the future, I believe that API access policies is an OOB feature that should handle this going forward, rather than creating something custom.
> API access policy defines the permissions and duration of access to an API.
> API access policy enables you to restrict access to inbound ServiceNow® APIs based on the authentication type and the specified filter criteria of the access policy.