Problem with OAuth2.0 --- Token management
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-16-2023 01:29 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-16-2023 01:40 AM
Try to set default grant type as client credentials
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-19-2023 03:07 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-19-2023 01:49 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-19-2023 03:02 AM
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();
}
}