Problem with OAuth2.0 --- Token management

Vincenzo Basile
Tera Expert

Hi,

I need to use a list of Web-service that use an authentication by OAuth2.0.

 

So I have register on our ServiceNow instance the application by the Application Registry (oauth_entity) and so I have obtained also the OAuth Entity Profiles (oauth_entity_profile), that I use in my Web-service authentication.

 

NOTE:

I haven’t specified any “OAuth API Script”

 

Now, by the webservice page (sys_rest_message) I use the UI Action “Get OAuth Token” to insert my credential and so obtain the following 2 tokens:

  • Refresh Token
  • Authentication Token

That are stored on the Manage Tokens area (oauth_credential).

 

All work correctly, every time that the Authentication Token expire, the system automatically recovers a new one by using of the Refresh Token.

This logic updates every time the expiration date of both the tokens.

 

But some time I identify an invalid Refresh Token, and so all the webservices go down.

NOTE:

The problem could be also happened if the webservice are not used for more time… but this for now is not a real problem because it is working every 10 minutes…

 

 

This is the error:
[[error: invalid_grant ]
[error_description: Invalid refresh token ]

 

 

 

 

To resolve the problem for other random time, I need to re-insert the credential by the “Get OAuth Token” in the webservice page (sys_rest_message).

 

There are some ways to automatize the credential authentication and so obtain automatically a new Refresh Token when something happen ??

 

NOTE:

I try to use the script, that execute the token requirement, but by script the “oauth_credential” table are note populated and I need to write the authentication credential on the script (I don't like it) and it’s not a real OAuth2.0

 

Could somebody help me to understand:

  • how store the credential
  • how use it automatically, when necessary (wrong Refresh Token), without write it clear
4 REPLIES 4

Shruti
Mega Sage
Mega Sage

Try to set default grant type as client credentials

ShrutiW_0-1684226373175.png

 

Unfortunatelly doesn't work 😞


I had also try to add the credential on the "Connections & Credentials" area,

but I don't know how to link it the this specif OAuth2.0 authentication 

Vincenzo Basile
Tera Expert

Unfortunatelly doesn't work 😞
I had also try to add the credential on the "Connections & Credentials" area,

but I don't know how to link it the this specif OAuth2.0 authentication 

But I have found a Workaraound.
on the "OAuth API Script” on the "postprocessAccessToken" method,
I have add a check of the "tokenResponse", if I find an error about "invalid_grant" the script call send an Event.
So in async way, if the event is the fist of the current day (this for evaoid loop), the script by the using the a sepecific "Connections & Credentials" execute therequest of a new Refresh Token and excute the updated of the "oauth_credential".

 

It work correctly 🙂

 

Here, if could be usefulf, the code of the script that execute the Refresh Token update by a specific "Connections & Credentials":

 

var Application_Registry_Name = event.parm1;
var ignore_today = event.parm2;
//Check if there are the first on today
var prev_event = new GlideRecord('sysevent');
prev_event.addQuery('sys_id', '!=', event.getUniqueValue());
prev_event.addQuery('name', 'event name');  //here the name of the event
prev_event.addQuery('sys_created_on', 'ON', 'Today@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()');
prev_event.setLimit(1);
prev_event.query();
if (!(prev_event.hasNext())) {
    getNewToken(Application_Registry_Name);
} else {
    if (ignore_today && ignore_today != '') {
        getNewToken(Application_Registry_Name);
    }
}

function getNewToken(Application_Registry_Name) {
    gs.log('Start ' + Application_Registry_Name, 'ReloadRefreshToken');
    //Get User:
    var credetial = new GlideRecord('basic_auth_credentials');
    credetial.addQuery('name', 'Connections & Credentials name'); //the name of the autheticathion credention record tored on "Connections & Credentials"
    credetial.setLimit(1);
    credetial.query();
    var account_user_name, account_password;
    if (credetial.next()) {
        var Encrypter = new GlideEncrypter();
        account_password = Encrypter.decrypt(credetial.password);
        account_user_name = credetial.user_name;
    } else {
        return;
    }
    // Get a refresh token 
    var oAuthClient = new GlideOAuthClient();
    var tokenRequest = new GlideOAuthClientRequest();
    tokenRequest.setGrantType('password');
    tokenRequest.setUserName(account_user_name);
    tokenRequest.setPassword(account_password);
    tokenRequest.setScope('useraccount');
    var tokenResponse = oAuthClient.requestToken(Application_Registry_Name, tokenRequest);
    var token = tokenResponse.getToken();
    //Token Update on oauth_credential
    var template = {
        'scopes': token.getScope(),
        'expires': token.getExpiresIn(),
        'token_received': token.getRefreshToken(),
        'type': 'refresh_token',
    };
    var now_GR = new GlideRecord("oauth_credential");
    var oauthClient = now_GR.addJoinQuery("oauth_entity", "peer", "sys_id");
    oauthClient.addCondition("name", Application_Registry_Name);
    now_GR.addQuery("type", "refresh_token");
    now_GR.setLimit(1);
    now_GR.query();
    if (now_GR.next()) {
        for (var key in template) {
            now_GR[key] = template[key];
        }
        now_GR.update();
    }
}