- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-20-2018 09:12 AM
I want to use ServiceNow scripts to get a pre-signed URL from Amazon S3 storage. The AWS JavaScript SDK can be used for this, and I read the Community post describing how this SDK can be imported into ServiceNow; however that method looks extremely fragile. I'd prefer presigning a URL without the SDK, if possible. Has anyone done something like this before?
UPDATE
ServiceNow does not have the functions to generate signatures in AWS Signature Version 4. Version 4 requires a signing key that is derived from your secret access key by a series of hash-based message authentication codes (HMACs). GlideCertificateEncryption can return the HMACs in base64 format, but the AWS signing key requires an HMAC-SHA256 function that returns output in binary format:
Use the digest (binary format) for the key derivation. Most languages have functions to compute either a binary format hash, commonly called a digest, or a hex-encoded hash, called a hexdigest. The key derivation requires that you use a binary-formatted digest.
AWS provides an example of creating the necessary binary format digest in Python (amazon.com, sigv4-signed-request-examples.html😞
hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
There seems to be a way of using the CryptoJS library to produce an equivalent to this using some custom functions for converting from a WordArray to byte array found here: https://stackoverflow.com/questions/29432506/how-to-get-digest-representation-of-cryptojs-hmacsha256....
Unfortunately, I've never been able to get CryptoJS working in ServiceNow Kingston as shown in Sift API and Request Signature Generation. I tested the solution from killswitch1111 on Cannot access SncAuthentication from application scope and it failed to get CryptoJS working, even after I pulled the correct version of CryptoJS from crypto-js on Google Code Archive.
The only way I can find to generate this signature is to stand up an entirely new service outside of ServiceNow that does nothing but sign S3 URLs in response to GET requests from ServiceNow. I was very much hoping to avoid that, but I can see no other option.
Solved! Go to Solution.
- Labels:
-
Integrations
-
Scripting and Coding
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-29-2021 08:06 AM
We are currently using a custom external API which we call from ServiceNow to generate signatures. We weren't ever able to get ServiceNow to generate signatures. This is probably because ServiceNow doesn't appear to have any functions which generate binary hashes. Other languages have two separate hashing functions: one for binary and one for hex hashing. Python is an example:
hash.digest()
Return the digest of the data passed to the update() method so far. This is a bytes object of size digest_size which may contain bytes in the whole range from 0 to 255.hash.hexdigest()
Like digest() except the digest is returned as a string object of double length, containing only hexadecimal digits. This may be used to exchange the value safely in email or other non-binary environments.
Since cloud storage API's like AWS and Azure expect binary digests, it's necessary to generate these using an API external to ServiceNow that generates binary hashes using a more competent language, such as Node.js or Python. Azure Functions or AWS Lambdas provide a simple way to create such a "helper" API for generating hashes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-20-2018 12:37 PM
Hi David,
I am trying to access the aws lex end point using your code. I want to access the below end point:
https://runtime.lex.us-east-1.amazonaws.com/bot/xyz/alias/xyz/user/5371/text%20%20HTTP/1.1
I am getting below error:
<InvalidSignatureException> <Message>Credential should be scoped to correct service: 'lex'. </Message> </InvalidSignatureException>
Can you please assist.
Thanks
Ravi Gupta
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-26-2018 10:07 AM
The service endpoint is hard-coded to...
endpoint: 'https://s3.amazonaws.com'
That endpoint results in "S3" for the AWS Service.
var amazonawsService = this.signingUtil.getService(this.endpoint);
Your endpoint uses the Amazon Lex service, not the Amazon S3 service. This script only supports S3.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-12-2019 07:41 AM
in order to get this to work do you need to have Amazon AWS Cloud enabled?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-12-2019 12:24 PM
I honestly don't know! My team tried to replicate this code in a dev instance of SNOW, and we could never figure out what module contains the AWSRESTRequestSigningUtil script. We ended up moving to Azure for our cloud hosting because a company we acquired had a large deployment in that cloud. We haven't tackled the problem of generating pre-signed URLs for Azure-hosted files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-07-2020 06:27 PM
Then "the accepted solution" should not be marked as such, as it'll never work, as it's based on a highly customised instance inwhich it was written in. Sure the code helps understand the process but that should be made clear at the top, to stop people wasting time on something that'll never work in their environment as it's reliant on core SN classes which do not exist OOTB and without knowing what's needed to be "switched on" the code doesn't provide a working solution.