Authenticate with OAuth Provider using Private Key (JWK)

Richard56
Tera Expert

Hello everyone, I am trying to obtain a bearer token from an OAuth 2.0 provider.
The provider has a public key (JWK), and I hold the corresponding private key.
To generate the JWT required for authentication, I need to add specific claims (e.g., iss, aud, exp, etc.) to the payload. This JWT will be used to authenticate with the OAuth provider, which will then return a bearer token.
I am having trouble setting this up in ServiceNow. Specifically, I’ve added the private key to the "Certificate" table with the type set to "Private Key," but I’m unsure how to proceed from there.
If anyone has experience with this, I would appreciate your guidance!

4 REPLIES 4

Randheer Singh
ServiceNow Employee
ServiceNow Employee

Hi @Richard56 ,
You can follow the steps provided in this KB article
https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0717946
Thanks,

Randheer

Thank you. I had issues at the first step when uploading the demo keystore file: jwtdemo.keystore: File type not permitted or mime type does not match the file content
In the tutorial, we are generating a demo jks. In my case, I have a private key that needs to be converted into a jks. To convert a private key to a jks file, we would have to have a certificate as well. The simplified "math" behind it is jwk(private key) + certificate = jks. Since we do not have a certificate in our case, we can create a dummy certificate to create our jks.

 

Here are the steps I did to make it work, and also the requirements for these steps. This is probably not the only way to do it, but this is how I made it work.
Requirements: openssl, keytool and python

Steps:

1. Create a PEM file with your private key (JWK)
I used python for this. Here is the python script: 

 

import json
from jwkest.jwk import KEYS

jwk_json = """
{
  "keys": [
    {
      "alg": "RS256",
      "d": "",
      "dp": "",
      "dq": "",
      "e": "AQAB",
      "key_ops": [],
      "kid": "TEST.2024-12-06",
      "kty": "RSA",
      "n": "",
      "oth": [],
      "p": "",
      "q": "",
      "qi": "",
      "use": "sig",
      "x5c": []
    }
  ]
}
"""

keys = KEYS()
keys.load_jwks(jwk_json)

# Convert KEYS object to a Python list
all_keys = list(keys)
# Grab the first key
rsa_key = all_keys[0]

private_pem = rsa_key.key.exportKey("PEM")
print(private_pem)

with open("test.pem", "wb") as f:
    f.write(private_pem)
 

2. Create a "dummy" self signed certificate using your newly created PEM key with openssl

openssl req -x509 -days 365 -key test.pem -out dummy.crt -subj "/CN=MyDummyCert"

 

3. Convert PEM and certificate to a p12 file

openssl pkcs12 -export -inkey test.pem -in dummy.crt -out test.p12 -name Test

 

4. Convert p12 file to JKS

keytool -importkeystore -srckeystore test.p12 -srcstoretype pkcs12 -destkeystore test.jks -deststoretype jks

 

and then, I followed the steps for the knowledge article you provided. I almost have it working now. ServiceNow uses new sn_auth.GlideOAuthClient() to create a JWT which is used in the body param "assertion" when retrieving a token from an endpoint. The endpoint I am trying to request a token from requires "kid" in the JWT header, do you know how I can set that header? I've tried using .setHeader(), ref(https://sn.jace.pro/docs/glideoauth/), but it seems like the function might have been removed, the logs tells me that the function cannot be found.

 

EDIT: Figured out where to set "kid" for header in JWT. You can set it in your JWT Keys Record (jwt_keystore_aliases) Thanks to @Jace Benson for helping me with this:

Richard56_0-1735760487755.png

 

 

Rahman4
Tera Guru

Hi there,

Did you manage to resolve this issue and what the final outcome was? If you could please share details of your configurations,

 

Many thanks

Hello @Rahman4, I managed to solve it. I responded to Randheer Singh, can you see the solution i posted?