Script for automatically updating Managed Oauth tokens in oauth_credential
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā06-07-2019 02:42 AM
Hello,
I am trying to automatize the refreshing of Oauth tokens that I use in the REST Messages, so I don't have to manually trigger it once the refresh token expires.
I know the Access and Refresh token is stored in the oauth_credential. Can someone help me find a script that checks if they expire and if they do generate a new one ?
Thank you !
- Labels:
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā06-11-2019 04:34 AM
Please check this answered link: https://community.servicenow.com/community?id=community_question&sys_id=cfdf07a5dbdcdbc01dcaf3231f96193d&view_source=searchResult
https://community.servicenow.com/community?id=community_question&sys_id=6df633f6dbf0a7c89d612926ca961945
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā05-03-2020 08:39 AM
You can have a Schedule Script Execution with the below script to automatically generate new access tokens once they are about to expire ( if there is a valid refresh token)
function refreshAccessToken(requestorId, oauthProfileId, token) {
if ( !(token && requestorId && oauthProfileId))
return;
var tokenRequest = new sn_auth.GlideOAuthClientRequest();
tokenRequest.setGrantType("refresh_token");
tokenRequest.setRefreshToken(token.getRefreshToken());
tokenRequest.setParameter('oauth_requestor_context','sys_rest_message');
tokenRequest.setParameter('oauth_requestor', requestorId);
tokenRequest.setParameter('oauth_provider_profile',oauthProfileId);
var oAuthClient = new sn_auth.GlideOAuthClient();
var tokenResponse = oAuthClient.requestTokenByRequest(null,tokenRequest);
var error = tokenResponse.getErrorMessage();
if (error)
gs.warn("Error:" + tokenResponse.getErrorMessage());
}
function isExpired(expiresIn, withinSeconds) {
if (expiresIn > withinSeconds)
return false;
return true;
}
function getToken(requestorId, oauthProfileId) {
if (!requestorId || !oauthProfileId)
return null;
var client = new sn_auth.GlideOAuthClient();
return client.getToken(requestorId, oauthProfileId);
}
function checkAndRefreshAccessToken(grRestMessage) {
if (grRestMessage.getValue("authentication_type") != "oauth2" )
return false;
var accountMsg = grRestMessage.getValue("name");
if (!accountMsg)
accountMsg = grRestMessage.getUniqueValue();
accountMsg = "Account=\"" + accountMsg + "\"";
var token = getToken(grRestMessage.getUniqueValue(), grRestMessage.getValue('oauth2_profile'));
var accessToken = token.getAccessToken();
if (accessToken) {
if (!isExpired(token.getExpiresIn(), 300))
return;
}
if (!token.getRefreshToken()) {
gs.error("No OAuth refresh token for Rest Message. Manual reauthorization required. " + accountMsg);
return;
}
if (isExpired(token.getRefreshTokenExpiresIn(), 0)) {
gs.error("OAuth refresh token for Rest Message is expired. Manual reauthorization required. " + accountMsg);
return;
}
gs.info("Refreshing oauth access token for Rest Message account. " + accountMsg);
refreshAccessToken(grRestMessage.getUniqueValue(), grRestMessage.getValue('oauth2_profile'), token);
}
var grAccount = new GlideRecord("sys_rest_message");
grAccount.addQuery("authentication_type", "oauth2");
grAccount.addNotNullQuery("oauth2_profile");
grAccount.query();
while (grAccount.next()) {
checkAndRefreshAccessToken(grAccount);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā09-09-2022 03:17 PM
Any idea why:
var tokenResponse = oAuthClient.requestTokenByRequest(null,tokenRequest);
tokenResponse.getErrorMessage() returns the message "invalid_request, Missing parameters: access_token"
The token from the oauth2_profile definitely has both an Access Token and Refresh Token.
Michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā09-12-2022 02:23 PM
Solved my own issue.
I'm a fan of script includes so what perfect place to add some of this code than in a script include. Well, it is, but I had a heck of time. Thought I'd share what I found in case others experience something similar.
Generally, when I'm calling the same method multiple times from a script include, for example, when in a while loop, I'll declare a variable to instantiate the script include outside the while loop and then use that variable along with the method inside the while loop. Pretty common practice for me.
However, in this case, it appears either the GlideOAuthClientRequest or GlideOAuthClient classes do react kindly to that. What I found was that I had to instantiate the script include for each loop instance.
For example, this pattern did not work:
var OAuthUtil = new global.MyOAuthUtilScriptInclude();
...
while (grAccount.next()) {
OAuthUtil.checkAndRefreshAccessToken(grAccount);
}
But this pattern did work:
while (grAccount.next()) {
new global.MyOAuthUtilScriptInclude().checkAndRefreshAccessToken(grAccount);
}
Not sure why but I'll let someone smarter than me explain away. All I know is I spent a good eight plus hours before I finally figured this out. Hope this "find" helps someone else.
Thanks,
Michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā04-25-2025 09:55 AM
Hi can you pleas share the process and script to get the token refresh automatically.