Restrict an endpoint from Basic Authentication
One of the most commonly used authentication mechanisms when you consume or produce a web service is Basic Authentication. Basic Authentication requires two credentials
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.
- Named: restricted.basic-auth.endpoints
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;
}
}
```- 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.
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.
https://www.servicenow.com/community/developer-articles/restrict-an-endpoint-from-basic-authentication/ta-p/2325659