- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-21-2019 01:49 AM
Hi,
At my client, we would like ServiceNow to read the groups as they are registered in GSuite. I run into an issue with this integration, as i seem to receive a OAuth token, but when i use it i receive a 403 error
From the google docs, i understand that you should (more or less) "impersonate" a user. However, i'm not sure if this is mandatory when using a Service Account in google. Because google created a service account, i do not have a client secret and client ID, but had to compile a .jks file from a certificate and use a JWT integration.
Any assistance will be greatly appreciated, as currently I think i tried everything i could think off.
Below a description of my configuration.
Using the JWT Provider and Application registry, I registered the credentials our Google team provided. Using these credentials I am able to click on the Rest Message (sys_rest_message) "Get oauth Token" which will show "OAuth token flow completed successfully" in the pop up. When i click on "Test" on the HTTP Method (sys_rest_message_fn), however, I receive this:
HTTP status: 403
Error message: Method failed: (/admin/directory/v1/groups) with code: 403 - Forbidden username/password combo
Error code: 6
Response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Not Authorized to access this resource/api"
}
],
"code": 403,
"message": "Not Authorized to access this resource/api"
}
}
Some key configurations I have:
Endpoint: https://www.googleapis.com/admin/directory/v1/groups?domain=<CLIENT_DOMAIN>
X.509 Certificate:
Record with a .jks file for authentication
JWT Keys:
Links to the X.509 Certificate:
OAuth Entity Scope:
Requesting the scope: https://www.googleapis.com/auth/admin.directory.group
NOTE: I verified that google grants the service accounts this scope. I also tried the .readonly version
OAuth Entity Profile:
Linking scope, Oauth Provider, JWT Provider
JWT Provider (blacked out parts is the ServiceAccount email provided by google)
1 Custom claim not pictured (scope: https://www.googleapis.com/auth/admin.directory.group)
Application Registry (OAuth)
I had to empty Client ID & Client Secret using a background script, otherwise i would not receive a token, because they are illegal parameters
Oauth entity profile: links to the OAuth entity profile configured (as described above)
I also tried to test my configuration with this script to debug:
initiateFlow();
function initiateFlow() {
gs.print('\nstart....');
var requestor = 'd244b8f0dbdc0c106380ef905b961911';
var requestor_context = 'sys_rest_message';
var oauth_provider_profile = '3e285fd0dbdc4810be87553c689619f1';
var oauth_provider_id = '';
var tokenRequest = new sn_auth.GlideOAuthClientRequest();
tokenRequest.setParameter('oauth_requestor_context', requestor_context);
tokenRequest.setParameter('oauth_requestor', requestor);
tokenRequest.setParameter('oauth_provider_profile', oauth_provider_profile);
tokenRequest.setParameter('oauth_provider_id', oauth_provider_id);
var oauthClient = new sn_auth.GlideOAuthClient();
var tokenResponse = oauthClient.requestTokenByRequest(null, tokenRequest);
var errorMsg = tokenResponse.getErrorMessage();
gs.print('Response code: ' + tokenResponse.getResponseCode() + '\nErrorMessage: ' + errorMsg);
if (tokenResponse) {
var token = tokenResponse.getToken();
if (token) {
if (token.getAccessToken()) {
gs.print('\nTOKEN RECEIVED:\n' + token.getAccessToken());
makeRest(token.getAccessToken())
}
}
}
}
function makeRest(recToken) {
gs.print('\nMake rest using token');
var endpoint = 'https://www.googleapis.com/admin/directory/v1/groups?domain=<CLIENT_DOMAIN>';
var sm = new sn_ws.RESTMessageV2();
sm.setEndpoint(endpoint);
sm.setHttpMethod('get');
sm.setRequestHeader('Authorization', 'Bearer ' + recToken);
var response = sm.execute();
gs.print('\n\nREST Response:\nBody:\n' + response.getBody() + '\nstatusCode: ' + response.getStatusCode());
}
Which results in this output
As you can see, it notes that a token is received (line 9-13)
All the way at the bottom, you can see the response is "403: forbidden"
*** Script:
start....
Ignore oauth entity from request. Use provider from oauth entity profile.
Getting JWTProvider for jwtProviderSysId = 92eb2cf4db9c0c106380ef905b9619eb
Getting JWTProviderConfig for jwtProviderId = 92eb2cf4db9c0c106380ef905b9619eb
Started to generate JWT
Successfully generated JWT
StorageEncrypter: ignoring already encrypted text starting with: }iO:S...
*** Script: Response code: 200
ErrorMessage: null
*** Script:
TOKEN RECEIVED:
ya29.c.Kl6iB3YTIpdRQYZUEF6YTBd_EGAkhhwnpKel_4qR7FopReqY4Mz0-3Ku-C7BT5AedA0oDiI3ehjOS4HVZ3LgaVvcI-Gs6yZrOhoWTsrFWj16zUlVYZQl_wnWd_wWmDjS
*** Script:
Make rest using token
*** Start Background transaction - system, user: system
*** Start Background transaction - system, user: system
Starting: SMTP Sender 2.015a962b37020200daa9a16043990e68, Trigger Type: Interval, Priority: 25, Upgrade Safe: true, Repeat: 1 Minute
Name: SMTP Sender 2
Job Context:
#Mon Oct 21 01:44:16 PDT 2019
Script:
*** Start Background transaction - system, user: system
*** Start Background transaction - system, user: system
Starting: events process 1.a0e84303db133300a898f7871d9619ae, Trigger Type: Interval, Priority: 25, Upgrade Safe: true, Repeat: 10 Seconds
Name: events process 1
Job Context:
#Mon Oct 21 01:45:41 PDT 2019
fcScriptName=javascript\:gs.processDelegatedEvents();
Script:
Starting: Flow Engine Event Handler.1d160122db0000106380ef905b9619d3, Trigger Type: Repeat, Priority: 100, Upgrade Safe: true, Repeat: 2 Seconds
Name: Flow Engine Event Handler
Job Context:
#Mon Oct 21 01:45:40 PDT 2019
Script:
Starting: Flow Engine Event Handler.5d160122db0000106380ef905b9619d5, Trigger Type: Repeat, Priority: 100, Upgrade Safe: true, Repeat: 2 Seconds
Name: Flow Engine Event Handler
Job Context:
#Mon Oct 21 01:45:40 PDT 2019
Script:
*** Start Background transaction - system, user: system
*** Start Background transaction - system, user: system
Starting: Flow Engine Event Handler.65160122db0000106380ef905b9619d9, Trigger Type: Repeat, Priority: 100, Upgrade Safe: true, Repeat: 2 Seconds
Name: Flow Engine Event Handler
Job Context:
#Mon Oct 21 01:45:40 PDT 2019
Script:
Completed: SMTP Sender 2 in 0:00:00.004, next occurrence is 2019-10-21 10:47:01
*** Start Background transaction - system, user: system
Starting: Flow Engine Event Handler.69160122db0000106380ef905b9619d7, Trigger Type: Repeat, Priority: 100, Upgrade Safe: true, Repeat: 2 Seconds
Name: Flow Engine Event Handler
Job Context:
#Mon Oct 21 01:45:40 PDT 2019
Script:
Completed: Flow Engine Event Handler in 0:00:00.005, next occurrence is 2019-10-21 10:45:53
Completed: Flow Engine Event Handler in 0:00:00.006, next occurrence is 2019-10-21 10:45:53
Completed: events process 1 in 0:00:00.009, next occurrence is 2019-10-21 10:46:01
Completed: Flow Engine Event Handler in 0:00:00.006, next occurrence is 2019-10-21 10:45:53
Completed: Flow Engine Event Handler in 0:00:00.006, next occurrence is 2019-10-21 10:45:53
Starting: Layer 2 Connections Creation.aeb1ecca7fa133001952baf8befa91ef, Trigger Type: Interval, Priority: 100, Upgrade Safe: false, Repeat: 10 Seconds
Name: Layer 2 Connections Creation
Job Context:
#Mon Oct 21 01:45:41 PDT 2019
fcScriptName=in the schedule record
Script:
GlideEventManager('physical_connections_creation').processDelegatedEvents();
Completed: Layer 2 Connections Creation in 0:00:00.007, next occurrence is 2019-10-21 10:46:01
*** Script:
REST Response:
Body:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Not Authorized to access this resource/api"
}
],
"code": 403,
"message": "Not Authorized to access this resource/api"
}
}
statusCode: 403
*** Script: 3600 null
[0:00:00.596] Total Time
thanks in advance for your time and effort!
Solved! Go to Solution.
- Labels:
-
Integrations
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-03-2019 11:52 PM
The integration is up and running now. This is my resolution:
1. Ensure the "sub" claim is filled with the email address of the admin
2. if you receive the error "OAuth flow failed. Verify the configurations and try again. Error detail:invalid_scope, Invalid downscoping, scopes should not be specified as a request parameter" re-configure your scopes:
- add a custom claim "scope" to your "JWT Provider" (space separated list of scopes)
- on the Application Registry record (oauth_entity), add the "Oauth entity scopes" record (same as in claim)
- make that on the "OAuth entity profile" the related list "OAuth Entity Profile Scopes" is EMPTY

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-05-2020 04:53 AM
In addition to the above..
When I wrote the last post I did not have the correct customer ID, but I did get manage to get the token-request working by removing the sub claim.
However, now having the right customer ID in a HTTP request that consumes that token against the actual Google API resource I do get the same error as you did:
But what was a solution for you (adding the sub claim admin user), prevents my logic from getting a token in the first place, so now I am stucked again..
Any ideas?
Anders
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-05-2020 05:27 AM
So i'm no longer at this client, so it is hard for me to really trouble shoot. THings I had to keep in mind:
your domain is everything after the @ in the email address (so for example to get the group list i gave the parameter "domain=service-now.com")
It says you have a username / password combo. Make sure that the fields client ID & client secret from step 3.4 are blank. (if you don't want to mess with the OOTB record / field states, save the record with a fake ID & secret, and use a background script to erase them.)
I did troubleshooting from python. That way i knew for sure that there is not unexpected logic converting my request. I stripped the service-now sauce, saw everything could work and then rebuild it in service-now.
See attachment for the python script. I'm not sure whether i used method 1 (commented out in this screenshot) or method 2 in the end. I did all these python scripts from a VM and just had a screenshot of this one. Sadly, i cannot retrace all my troubleshooting steps. (blacked out part in 1 is the full email address (e.g. ward.van.hoof@service-now.com), and the blacked out part in "results" is the domain (e.g. service-now.com)
EDIT: one more thing to look at: you can have the endpoint like this /admin/groups/customer/<id>/ etc
or like this /admin/groups?domain=<domain.com>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-05-2020 08:19 AM
Thank you again Ward!
I did blank the client ID & client secret fields..
Despite tons of PowerShell experience python doesn't seem intuitive to me, so I will have to look more into it next week.
I will return eventually with some comment to you, so others can learn from our efforts and mistakes.
-Anders

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-08-2020 01:16 AM
Just to finish this...
We managed to get it working when the Service Account was setup correctly following this third party guide. It turned out that the "ENABLE API ACCESS" step in that guide had not been done.
After that I tried populating the Client ID field to see if that would brake it again, but it did still work. I imagine that you while trying to get it working concluded that it had to be blanked (by background script due to it being mandatory), but it does seem that the value in the client ID field does not matter.
I would not have succeeded without your help since I didn't have endless time to succeed in the context of working for a customer.
THANK YOU!
-Anders

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-05-2020 01:57 AM
Thank you Ward, that was very helpful!
For my setup to work the "sub" claim had to be be unspecified, but that might relate to how the Service Account is setup, and since I am doing this for a customer I don't have access and haven't setup the Service Account in the first place - only received informations about it.
I will definitely reference your post. You're a rockstar! 🙂
Sincerely,
Anders