Curl Command throwing' invalid grant error' on Windows command line - docusignapi

I have generated the JWT Token for DocuSign through the https://jwt.io .The signature is verified.
Now to obtain the Access token I am using following Command in Curl,on Windows Command line tool.Rrefering the Document https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken.I am getting "invalid Grant".What is the problem with my request?I know my token is correct because the token verifies the signature.
curl --data "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=YOUR_JSON_WEB_TOKEN" --request POST https://account-d.docusign.com/oauth/token

invalid_grant is the the publicly facing version of several errors rolled together. If you've hit your limit of troubleshooting, I'd recommend opening a case with DocuSign Support, and provide your Demo Account ID, UserID, Integrator Key and the value of an x-DocuSign-TraceToken of a failing assertion. The plaintext version of your assertion would be helpful as well.
Here's a few things to check:
aud value - must be exactly account-d.docusign.com (for demo) or account.docusign.com for prod. Including https:// or any other value will fail.
sub value - must be an active userID (in GUID format) in the appropriate environment.
iss value - must be a valid client ID
Private Key used for signing - must be associated with the Client ID in the correct environment. If you're using a key generated in Production but the assertion is directed to account-d.docusign.com it will fail. In some cases it can take a few minutes for a newly generated keypair to be valid in the Account Server, so if you've just generated that key, wait a bit and try again.
Timestamps used - Your exp value must not have passed, and if you are using an nbf value, it must be in the past. Confirm your computer's clock is correctly configured - if it's dramatically off, your application could be generating invalid assertions because of that.

The pro-tip is to use a library to generate the JWT and convert it to an Access Token.
See the JWT examples for code examples in many languages. The examples use either a JWT method from a DocuSign SDK or a lower level JWT library.
C# .NET Core https://github.com/docusign/eg-01-csharp-jwt-core
C# .NET Framework https://github.com/docusign/eg-01-csharp-jwt-framework
PHP https://github.com/docusign/eg-01-php-jwt
Java https://github.com/docusign/eg-01-java-jwt
Node.js https://github.com/docusign/eg-01-node-jwt
Python. https://github.com/docusign/eg-01-python-jwt
Ruby https://github.com/docusign/eg-01-ruby-jwt
See the repositories’ Readme files for installation and configuration instructions.

Related

Validating Google sign in ID token in Rust

I'm interested in validating a Google ID token that is returned upon a successful Google Sign In attempt. I have a Rust based webapp where I:
Offer Google Sign in via Javascript, upon successful authentication, I get back, among other things, a Google ID token.
My Javascript code submits this Google ID token to my backend server (written in Rust) along with other info (i.e. user's account ID, current email etc).
I'd like to verify the integrity of this ID token via the directions cited in Google's official docs https://developers.google.com/identity/sign-in/web/backend-auth before I can "trust" that the submitted user's info (i.e. user's account ID, current email etc) is valid and is not a malicious request.
Example of what I'd like to achieve: Validate Google Id Token
What I've tried:
Thus far, I've attempt to use https://lib.rs/crates/google-signin with no luck, as I get the following error when attempting to use it as a dep:
cargo check
Updating crates.io index
error: failed to select a version for the requirement `untrusted = "^0.5"`
candidate versions found which didn't match: 0.7.1, 0.7.0, 0.6.2
location searched: crates.io index
required by package `webpki-roots v0.10.0`
... which is depended on by `hyper-rustls v0.6.0`
... which is depended on by `google-signin v0.3.0`
... which is depended on by `<my project> v0.0.1 (<my project>)`
it appears that the crate's link to the repo is broken, so no ability to submit an Issue.
I've tried https://github.com/Byron/google-apis-rs but I can't seem to find useable code in the generated output.
What are folks using to validate ID tokens in Rust?
Unfortunately there is no official sdk for rust, and those 2 are also not good anyways since they use token retrospection endpoint to validate, so you will have a latency on each token validation.
Its better to fetch&cache jwks and validate locally, the best crate which I've found so far is https://crates.io/crates/jwks-client . I'm interested in Firebase ID tokens so the jwks url for that is https://www.googleapis.com/service_accounts/v1/jwk/securetoken#system.gserviceaccount.com . It works fine but has some critical limitations:
it does not auto-refresh keys, so you would need to implement a daemon which would fetch keys periodically. This is very important since from my experience google does rotate jwks quite often.
its not thread-safe, since underlying key store is a simple vector, so you would need to extend it a bit
Also https://medium.com/#maylukas/firebase-token-authentication-in-rust-a1885f0982df seems to be a pretty informative guide

Error: The received token is of incorrect token type -- What should the token look like?

I recently registered to Microsoft Azure and set up a Cognitive Services Account. Using the instructions from the Text Translation API Documentation I was able to retrieve an authentication token from the /issueToken service using the interactive online example. However, if I want to use that token (for example for the interactive /translate example) I end up with the response
<html><body><h1>Argument Exception</h1><p>Method: Translate()</p><p>Parameter: </p><p>Message: The received token is of incorrect token type.</p><code></code><p>message id=0344.V2_Rest.Translate.3D8A6FF1</p></body></html>
What am I doing wrong? What should the token look like and in what format should I supply it? In the online example I specified the token by setting the appid field to "Bearer [token]" where [token] is the response from /issueToken.
In my case the token is a 687 characters long string which can be separated into three parts (using '.' as delimiter). The first two parts are base64-encoded and just contain some JSON-encoded information that stays constant (except the expiration date field). The third and last part changes everytime and can not be decoded using base64. Instead of supplying the full token I also tried to just use various substrings of the full token but without any success so far.
I also tried authenticating via curl using the Authentication-header instead of the appid-field, which also did not work for me.
The token actually has to look like it is described in the question text (at least as of now). The problem in my case was that I used the wrong subscription key. Note here: You get a different key for the translation API and the speech API each; even though both run under Cognitive Services and even if you connect both through the same resources.
I post this as an answer to my question because I want to confirm that all the steps listed above are correct and because I hope that it may help people who do the same mistake as I did.

DocumentDB UnauthorizedException: "The MAC signature found in the HTTP request is not the same as the computed signature."

Sporadically I had UnauthorizedException when requesting the documents from DocumentDB. The issue looks similar to Azure DocumentDB - The MAC signature found in the HTTP request is not the same as the computed signature, so I believe that problem is not solved.
Microsoft.Azure.Documents.UnauthorizedException :
Message: "The MAC signature found in the HTTP request is not the same as the computed signature.
Request URI: rntbd://db5prdddc01-docdb-1.documents.azure.com:14245/apps/35e0fabb-e03e-48d4-90ad-7b91b63c0153/services/9bb95f7b-9ad6-4128-a66a-de68279d5124/partitions/44a24d42-a85c-42cc-98c4-fc8a733245ac/replicas/130953283548138839p/
UPDATE: The issue was fixed, special thanks to Andrew Liu!
Happy to hear you are no longer experiencing this issue :)
Posting here for everyone else's benefit...
If you see an issue like this, it means that there is an authentication header mismatch between the application and database. This can be a result of many things... including an incorrect auth key, system clocks out of sync, or an issue with how the auth header is generated.
First-Party DocumentDB SDKs
If you are using one of DocumentDB's 1st party client SDKs - it's most likely an incorrect auth key or a system clock issue...
If those look good, than there is a bug on DocumentDB's end. If you are experiencing issues - please contact me (askcosmosdb {at} microsoft.com) with a few activity ids + timestamps + stacktrace, and I can help you look in to the issue.
Rest API
The header is rather tricky to put together... Here are some tips for constructing the auth header:
All parameters (verbs, resource type, date, etc.) must be lower case prior to signing EXCEPT when using id-based routing.
For id-based routing, you will need to sign the full path to the resource (e.g. dbs/MyDatabase/colls/MyCollection/docs/MyDocument); not just the resource's id (e.g. MyDocument). Please note that the path is case-sensitive... while, all the other parameters should be lower case.
The key is Base64 encoded.
The text to be signed should be utf-8 encoded.
The generated auth token is a SHA256 HMAC and should be Base64 encoded.
As with all HTTP headers, the signature (including the signed token) should be URL encoded (e.g. + needs to be encoded as %2B).
Full documentation and sample code, see: https://msdn.microsoft.com/en-US/library/azure/dn783368.aspx
Check for static client method. Is possible that you are using a client with a Read-only Key by mistake.
Trying to write using a Read-only Key throws that exception.
I faced the same problem while I used the primary connection string, when I changed the connection string to secondary, it worked for me.
We could able to resolve the issue with below workaround :
In Azure Portal -> Azure Cosmos DB for MongoDB -> -> Connection strings, there will be
Read-write Keys
Read-only Keys
if getting error while reading add use PRIMARY CONNECTION STRING in Read-only Keys.
if getting error while writing add use PRIMARY CONNECTION STRING in Read-write Keys.
use it based on what your application are doing

well-formed JWT but still getting merchant_error

I'm trying to set up In-App Payments for a Chrome Packaged App. When I switch the SellerSecret and SellerIdentifier from the sandbox to my own I get an merchant_error when I call buy().
As far as I can tell, this error seems to indicate that the JWT is not well-formed (but the only difference is switching out the sample secret and identifier with my own).
I've used the JWT Decoder ( https://developers.google.com/wallet/digital/docs/jwtdecoder ) and it looks fine.
Here's the JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMDQwNDkxNDU3OTM0MTYxMzI0MiIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZVwvcGF5bWVudHNcL2luYXBwXC9pdGVtXC92MSIsImV4cCI6MTM5MjkxNTg3NCwiaWF0IjoxMzkwMzIzODc0LCJyZXF1ZXN0Ijp7Im5hbWUiOiJEYW4ncyBQaWVjZSBvZiBDYWtlIiwiZGVzY3JpcHRpb24iOiJUZXN0IFB1cmNoYXNlIDEiLCJwcmljZSI6IjEwLjUwIiwiY3VycmVuY3lDb2RlIjoiVVNEIiwic2VsbGVyRGF0YSI6InVzZXJfaWQ6MTIyNDI0NSxvZmZlcl9jb2RlOjMwOTg1NzY5ODcsYWZmaWxpYXRlOmFrc2RmYm92dTlqIn19.SHwbbWiJMnyXxui-WbaDs3Z1_7mdn5lFWCJatmug1Rg
Can anyone help out?
Thanks!
-Daniel
UPDATE: I just generated a JWT using the ruby sample code here https://developers.google.com/wallet/digital/docs/tutorial and when using my sandbox secret and ID it's fine but when I use my own secret and seller id it fails. Here's generated JWT from Ruby:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMDQwNDkxNDU3OTM0MTYxMzI0MiIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZS9wYXltZW50cy9pbmFwcC9pdGVtL3YxIiwiZXhwIjoxMzkwMzUzOTU0LCJpYXQiOjEzOTAzNTAzNTQsInJlcXVlc3QiOnsibmFtZSI6IlBpZWNlIG9mIENha2UiLCJkZXNjcmlwdGlvbiI6IlZpcnR1YWwgY2hvY29sYXRlIGNha2UgdG8gZmlsbCB5b3VyIHZpcnR1YWwgdHVtbXkiLCJwcmljZSI6IjEwLjUwIiwiY3VycmVuY3lDb2RlIjoiVVNEIiwic2VsbGVyRGF0YSI6InVzZXJfaWQ6MTIyNDI0NSxvZmZlcl9jb2RlOjMwOTg1NzY5ODcsYWZmaWxpYXRlOmFrc2RmYm92dTlqIn19.6enjLDpM-fxg69-XtcllsyVXBqRNbdhhBzXSr7jmyCM
I still get a merchant_error when I call buy() with the above jwt.
When you switch to your "own" (assuming you meant production id/secret) are you also switching your calls to production buy()
<script src="https://wallet.google.com/inapp/lib/buy.js"></script>
Update:
Useful info referencing #Danprime's comment:
Chrome Apps -> Wallet for Digital Goods
For Apps, you must call buy() with an extra parameter called parameters. This parameter currently has one field, env, which specifies the environment in which to process a payment. You can set this field to either prod (production server that accepts real credit cards), or sandbox (test server that accepts test credit cards to simulate transactions). The default setting is sandbox.
Your type is doubly escaped google/payments/inapp/item/v1 also in the jwt, the issuer looks like it starts with 00.
Are you using PHP to generate it? There should be an option to convert the object to JSON without escaping strings.
Can you double check that it actually begins with 00?

What pattern for constructing and verifying an access token for a web application?

We have a web application which consists of two parts (among others): a 'shell' written in Java running in Jetty using Windows authentication through Waffle, which shows a 'component' written in ASP.NET running in IIS using Windows authentication. Both parts are served from the same host, but (of course) from different ports.
As it stands, a user first must sign in to the shell, and then when the component is loaded the user must sign in again. We want to get rid of that second sign-in step.
From what I've seen and read, e.g. about claims-based authentication and OAuth, the standard pattern for that is the following:
After signing in to the shell, the shell constructs a 'token' with the user's Windows account name, which it sends back to the browser.
The component does not use Windows authentication, but instead the browser sends it the token.
The component verifies that it trusts the token, and uses the identity from that token.
(In our case the simplest technique is to put the token in a cookie, since both shell and component run on the same server, and HTTP cookies are not port-specific, so the browser will automatically send the shell's token to the component.)
Now I see several ways to construct and verify the token, like:
(a) The token contains the Windows account name, encrypted with a symmetric key that is hardcoded into both shell and component, or generated and agreed at installation time or start-up time.
(b) The token contains the Windows account name, signed using a private key, and verified using the corresponding public key. This key pair is generated at installation time.
(c) The token contains a GUID, and the component's server side makes a call to the shell's server side to verify its validity and get the Windows account name.
I think I prefer (b), since (a) seems too 'hardcoded', and (c) is more likely to give scaling issues. Also, we already have a private/public key pair in place in the form of an SSL server certificate in the shell which is trusted by the component.
My main concern with (b) is that the token will contain an (X.509?) signature, which means the token could become fairly large. (Would it?) Also I'm not (yet) familiar with techniques to create a signature in Java, and verify it in .NET.
My question: What is the standard/recommended pattern to use here? What alternatives have I overlooked? Is there a standard protocol that we could use here?
You are on the right track.
Yes, the idea is to have the shell generate a token that cannot be forged (generated by anything/anyone but the shell) that can be verified by the component.
You are right that the token can become quite large. It will not become so large as to be unworkable (i.e. larger than a browser can handle), but it can become a performance issue.
In general, any component that accepts HTTP traffic with any kind of cached authentication is going to have a preferred format for that cached authentication. In your current implementation, after the user signs into the component (the second sign in step) the component will issue some kind of cookie containing identification credentials it will accept for subsequent requests. So the best thing would be for the shell to create exactly those credentials.
Failing that, it's quite reasonable for you to use your option (b) of creating a signed certification form the shell that the component can verify and then replace with its preferred form of authentication credential.

Resources