JSON Web Tokens (JWT) Generator?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-24-2015 08:48 PM
What is the best way to generate a JSON Web Token (JWT) in ServiceNow?
There are heaps of implementations in different languages out there (i.e. JSON Web Tokens - jwt.io) and I wrote one myself in Java, but without a MID server I can't run that java code, and I don't want to use MID.
- Is there an out of the box way to generate a JWT SHA256withRSA in servicenow giving the p12 file?
- Or I could rewrite it in a script include. But I'll have to find an equivalent to some java classes java.security.PrivateKey, KeyStore, Signature,... which I couldn't find.
- The only other option that I can think of is to take one of the open source Javascript implementations, refactor it, and put it as a Script include. But it's not going to be easy.
Best also if the solution can be implemented/used in a scoped app.
Thanks,
Michel
- Labels:
-
Scripting and Coding

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2015 06:42 AM
Hey Chris,
If you have luck w/ jsrsasign let me know. I'm following this thread as well.
Thanks,
Bryan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2015 07:38 AM
All,
I was able to work through the issues and got NOW to generate a JWT that verified in third party tools. I was missing library in the minified script bundle that I made. Now I just have to convert it to a Script Include (I've been running via Scripts - Background for testing.)
I've had trouble with this step in the past, but let's hope it can just work when stuff in an initialize function.
- Chris
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2015 08:50 AM
Here's an update set and some sample code for testing that I was able to verify. This is definitely provided with no warrantees or support, as I just worked on it quickly to get what I needed (signing and verifying JWTs.)
The Private Key and Public Cert below are from the source of the JSRSASign examples, so please never use them for anything (other than testing, of course.)
var j = new JSRSASign();
var z4PrvP5PPem = "" +
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEogIBAAKCAQEA33TqqLR3eeUmDtHS89qF3p4MP7Wfqt2Zjj3lZjLjjCGDvwr9\n" +
"cJNlNDiuKboODgUiT4ZdPWbOiMAfDcDzlOxA04DDnEFGAf+kDQiNSe2ZtqC7bnIc\n" +
"8+KSG/qOGQIVaay4Ucr6ovDkykO5Hxn7OU7sJp9TP9H0JH8zMQA6YzijYH9LsupT\n" +
"errY3U6zyihVEDXXOv08vBHk50BMFJbE9iwFwnxCsU5+UZUZYw87Uu0n4LPFS9BT\n" +
"8tUIvAfnRXIEWCha3KbFWmdZQZlyrFw0buUEf0YN3/Q0auBkdbDR/ES2PbgKTJdk\n" +
"jc/rEeM0TxvOUf7HuUNOhrtAVEN1D5uuxE1WSwIDAQABAoIBAA41OeJmLx6SAlx4\n" +
"3OfiYhaoh/DZFIDhvCy+JMLdw3gafWz9PuYUiR/L5s8CZHhhvS+/RFhuG/238YGH\n" +
"XjV+3BRWoJlj0Ra5cW3euFUWBWsGR0SbftnG8zFSOgy/BCuG7uVMeak4leOCcNfY\n" +
"aA/Zw8wk3z80k0hqyg94iz3Z0RGGiBg1cXIwb908eq6792dpYRxyoRB29EUYwE3I\n" +
"wFSlfTWYTGoyeJfaaidwOCEKwgZfebsel5taFz9Iumke/HI3IbAqXDF3T91jLLx4\n" +
"E5bGU9EWSxR675IjR5T4opeBtv3h5ML0//wq3GzukpiP8wrTJsqbhyanK/l2+xjy\n" +
"aGuuFqECgYEA8K33pX90XX6PZGiv26wZm7tfvqlqWFT03nUMvOAytqdxhO2HysiP\n" +
"n4W58OaJd1tY4372Qpiv6enmUeI4MidCie+s+d0/B6A0xfhU5EeeaDN0xDOOl8yN\n" +
"+kaaVj9b4HDR3c91OAwKpDJQIeJVZtxoijxl+SRx3u7Vs/7meeSpOfECgYEA7a5K\n" +
"nUs1pTo72A+JquJvIz4Eu794Yh3ftTk/Et+83aE/FVc6Nk+EhfnwYSNpVmM6UKdr\n" +
"Aoy5gsCvZPxrq+eR9pEwU8M5UOlki03vWY/nqDBpJSIqwPvGHUB16zvggsPQUyQB\n" +
"fnN3N8XlDi12n88ltvWwEhn1LQOwMUALEfka9/sCgYAMH2ca4emVj/te/lrlQKzl\n" +
"iDGRY+0kV9shnVmv5ccIJjT0khZF44ZAbbbo6GPCLEq04r86qYAq0woz06Yq+IlE\n" +
"c1sOFtPG6Y3e7twvx1+2NelKvKIRCU+ZbJb3gyd4jZY0iu+HjCu5C4O3wTO2A6IM\n" +
"XHBydSB7LyJ6d3taZmcTsQKBgDvm0k1EODf1LkHs4JBd0w65wa2juu5XgxsEW34h\n" +
"P1NIIUL6oeQwNEEj1c5Vg2XPSlIrb4/L8bEfaNT1vRktGp9exiRGLnrS55EoSitz\n" +
"VjoQQV+ndcj/a1XR+iYYCCRMv4NErs+0wBYhXPIuyRfLuECdOQvG2QDITi6Lan7U\n" +
"HlTjAoGAInfGmkb2jNkPGuNiZ+mU0+ZrOgLza/fLL9ErZ35jUPhGFzdGxJNobklv\n" +
"sNoTd+E2GAU41YkJh24bncMLvJVYxHHA5iF7FBWx1SvpEyKVhhnIcuXGD7N5PbNZ\n" +
"zEdmr9C6I7cPVkWO+sUV7zfFukexIcANmsd/oBBGKRoYzP5Tti4=\n" +
"-----END RSA PRIVATE KEY-----\n";
var z4CertPem = "" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADAaMQswCQYDVQQGEwJVUzEL\n" +
"MAkGA1UECgwCWjQwHhcNMTMwODI4MTgyODM0WhcNMjMwODI4MTgyODM0WjAaMQsw\n" +
"CQYDVQQGEwJVUzELMAkGA1UECgwCWjQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n" +
"ggEKAoIBAQDfdOqotHd55SYO0dLz2oXengw/tZ+q3ZmOPeVmMuOMIYO/Cv1wk2U0\n" +
"OK4pug4OBSJPhl09Zs6IwB8NwPOU7EDTgMOcQUYB/6QNCI1J7Zm2oLtuchzz4pIb\n" +
"+o4ZAhVprLhRyvqi8OTKQ7kfGfs5Tuwmn1M/0fQkfzMxADpjOKNgf0uy6lN6utjd\n" +
"TrPKKFUQNdc6/Ty8EeTnQEwUlsT2LAXCfEKxTn5RlRljDztS7Sfgs8VL0FPy1Qi8\n" +
"B+dFcgRYKFrcpsVaZ1lBmXKsXDRu5QR/Rg3f9DRq4GR1sNH8RLY9uApMl2SNz+sR\n" +
"4zRPG85R/se5Q06Gu0BUQ3UPm67ETVZLAgMBAAGjUDBOMB0GA1UdDgQWBBQHZPTE\n" +
"yQVu/0I/3QWhlTyW7WoTzTAfBgNVHSMEGDAWgBQHZPTEyQVu/0I/3QWhlTyW7WoT\n" +
"zTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQDHxqJ9y8alTH7agVMW\n" +
"Zfic/RbrdvHwyq+IOrgDToqyo0w+IZ6BCn9vjv5iuhqu4ForOWDAFpQKZW0DLBJE\n" +
"Qy/7/0+9pk2DPhK1XzdOovlSrkRt+GcEpGnUXnzACXDBbO0+Wrk+hcjEkQRRK1bW\n" +
"2rknARIEJG9GS+pShP9Bq/0BmNsMepdNcBa0z3a5B0fzFyCQoUlX6RTqxRw1h1Qt\n" +
"5F00pfsp7SjXVIvYcewHaNASbto1n5hrSz1VY9hLba11ivL1N4WoWbmzAL6BWabs\n" +
"C2D/MenST2/X6hTKyGXpg3Eg2h3iLvUtwcNny0hRKstc73Jl9xR3qXfXKJH0ThTl\n" +
"q0gq\n" +
"-----END CERTIFICATE-----\n";
var key = z4PrvP5PPem;
gs.print(key)
// Header
var oHeader = {alg: 'RS256', typ: 'JWT'};
// Payload
var oPayload = {};
var tNow = new GlideDateTime().getNumericValue();
var tEnd = new GlideDateTime().getNumericValue() + (5*60*1000);
gs.print(tNow);
oPayload.iss = "https://jwt-idp.example.com";
oPayload.sub = "mailto:mike@example.com";
oPayload.nbf = tNow;
oPayload.iat = tNow;
oPayload.exp = tEnd;
oPayload.jti = "id123456";
oPayload.typ = "https://example.com/register";
// Sign JWT, password=616161
var sHeader = JSON.stringify(oHeader);
var sPayload = JSON.stringify(oPayload);
var firstkey = j.getJWT(sHeader, sPayload, key);
gs.print("WHOLE TOKEN - " + firstkey);
gs.print("KEY SIGNATURE - " + firstkey.split('.')[2]);
gs.print(j.verifyJWT(firstkey, z4CertPem));
gs.print(j.decodeJWT(firstkey));
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-02-2015 01:15 PM
I've started looking at JWT just out of curiosity, but sooner than I thought I needed to use OAuth2 to authenticate with a third party. I knew it was going to be hard to implement JWT. So I went for OAuth 2.0 for Web Server Applications. ServiecNow redirects the user to the Third party's OAuth 2.0 server, authenticates it, and obtains consent from the user. Now that I hold the refresh token, I use it in scheduled job to obtain a new access token when the current one expired.
Great effort chrisc.! Unfortunately I don't have the capacity to test this right now. I'll wait for feedback from the community and I'll mark it as the correct answer accordingly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-11-2016 09:53 AM
I've got a need for this so I can authenticate to Google and this is actually working well for me without much modification. The only changes I had to make were to add claims that Google specifically requests and to adjust the issue and expiration times to be in seconds rather than milliseconds.
One other gotcha. If you're using this in Eureka you'll need to handle the JSON.stringify somehow. It's not available OOB in Eureka, it may be in Fuji and definitely is in Eureka.