DocuSign account cannot get JWT token - c#

I have two accounts of DocuSign, both have the same config on the Setting section. But the first one even though expires of the trial still can send the envelopes. The second one gets invalid_request when I tried to get the JWT token base on client_id, user_id, and private_key.
Do we need to enable some config to allow it? Thanks in advance.

A couple of things:
Are you using a trial (login via www.docusign.net) or developer demo account (login via demo.docusign.net)? You should only use developer demo accounts while developing with DocuSign.
To get a free developer demo account click the link at the top right of the developer center page. Demo accounts do not expire, but their envelopes that are over 30 days old are automatically deleted.
invalid_request can be cause by a number of different issues. Additional information is available in the body of the response. Please see what it is and then edit your question to add the information.
Added
For JWT invalid_request errors, the recommended steps are:
Get the DocuSign code example running with JWT grant. For C#, this repo.
Once that works, you'll know that the problem is in your code, not in the settings of the integration key (the client id), the private key, etc.
Check that your computer's clock settings are correct--the timezone and the day/date. These are used by JWT.
Check that you are specifying a user's guid id to be impersonated. This is also referred to as a user's "API User Id"
Check the body of the API response for additional debugging information.
If you receive the error "consent_required", that is good news since it indicates that your JWT grant was correct, except that the person being impersonated hasn't yet granted consent to be impersonated. To fix, see this blog post.

Related

How to completely sign out a user using Oauth Prompt?

I have been following the Oauth prompt sample Oauth Sample. Its working great when I login properly and get a token. However I am working on the use case when a user logs in using the wrong credentials. I am using await botAdapter.SignOutUserAsync(innerDc.Context, ConnectionName, null, cancellationToken); to sign the user out and it works since Oauth gets prompted again. However when the user clicks on sign in button again, it takes the wrong credentials again ( i.e same logged in credentials because of browser cache ) and doesn't allow the user to use a different account. I am looking to gracefully sign the user out so that he can choose another account to login. I understand if I add this to the right tenant (add my bot to right AD identity) it wont allow the wrong email/credentials to even get through but its something I have to work through for now. I don't know if this is intended but the sign out only destroys the token doesn't log you out of Microsoft online.
Thanks
Given that the SignOutUserAsync method only signs a user out of the token server, my guess is you will need to implement a custom method to handle a full sign out. This doc discusses sending a sign-out request and should serve as guidance on how to setup. If this isn't a perfect match, other options are listed in the menu tree.
Instead of relying on the SignOutUserAsync method, you would implement this feature in its place.

Docusign: Incorrect permissions requested

I am trying to obtain Admin consent for external application.
So I prepared link for an administrator of another company. Here is a link
As you can see:
scope=openid
admin_consent_scope=signature%20impersonation
But when administrator of target organization loggining in - he see the following screen
As you can see - it is requesting only "Obtain user information". But I expected to see permissions as in documetation:
After administrator clicked "Accept" - my app still gets an error consent_required when it generates JWT token.
Ok, had a call with Docusign support. They have a bit outdated specs.
The link should not have admin_consent_scope parameter and all scopes must be in scope parameter. Got it working.

How access token is validated for accessing protected resources in token based mechanism?

I want to do token based mechanism where I would be having either SPA or mobile apps supporting multiple clients.
Use case of my web service engine and my application:
My web application: Client will do registration of their application either SPA or mobile apps.They will get client id on registration.Only client id as secret key would be compromised in case of SPA or mobile apps hence I am just providing clientid.
Web service engine: Support multiple client with managing session of each user after login in to respective application of clients.
So let's say there are 2 client who have register their application in to my web application :
Client 1 : MyApp1
Client 2 : MyApp2
Now if MyApp1 have 2 users with John and Stephen and if they login in MyApp1 then i want to manage session for those users with token based mechanism. Now if John and Stephen wants to access protected resource then they can access only through valid accesstoken.
Same goes for MyApp2.
For token based mechanism I have seen lots of question referring to this below article only:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
But the only confusion part in above tutorial and in most of the tutorial is after validating user name and password and generating access token. Does above tutorial is storing access token in server side cookie for validating accesstoken when request comes to access protected resource?
I am really confused here. I know accesstoken validation happens inside [Authorize attribute] but I am not getting without storing accesstoken how above tutorial is validating accesstoken.
My thought is like may be when request comes for accessing protected resources access token is encrypted or decrypted based on machine key attribute in webconfig and this is how access token is validated inside [Authorize] attribute but I am just not sure about this.
You can control what information goes inside a token. Look at the SimpleAuthorizationServerProvider class in the article:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
Use the Claims to store anything you need regarding to the user, their username or roles and this is what happens in the article you referred to.
The token generated already contains that information about the user.
This is taken from the article :
The second method “GrantResourceOwnerCredentials” is responsible to
validate the username and password sent to the authorization server’s
token endpoint, so we’ll use the “AuthRepository” class we created
earlier and call the method “FindUser” to check if the username and
password are valid.
If the credentials are valid we’ll create “ClaimsIdentity” class and
pass the authentication type to it, in our case “bearer token”, then
we’ll add two claims (“sub”,”role”) and those will be included in the
signed token. You can add different claims here but the token size
will increase for sure.
This is why you do not need to store the token anywhere,the token is self contained and everything is stored inside it in an encrypted form. Don't forget that before you add a claim containing the username you have already validated the username and password, so you can guarantee that the token is created correctly for a valid user / password combination. Of course you do not want to store the password inside the token, the whole point of tokens is to avoid doing that. Passing passwords to an API all the time does increase the risk of them being stolen, tokens are much better for this.
Finally, the tokens expire after a time you control, usually they are short lived so even if someone does get their hands on one they will not last long.
If you take care of how you pass the tokens, meaning in the Authorisation Header over an https call then you are as protected as you can be and the headers will be encrypted. The point here is to never issue calls like this over basic http.
The author of the article you referenced is a well respected authority in this particular area and currently a Microsoft MVP and you are basically in good hands. Keep reading his articles, but pay attention to the details.
----------- Clarification related to JWT format --------------
yes the JWT token will contain information related to its issue date and expiry date as well. I have an article of my own on this : https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/
Look at the calls which create the token and look at the information returned in the screenshots.
In my example the token contains the actual encrypted token, the token type, seconds it expires in, the audience which is the ClientID, when it was issued and when it expires.
This is just an example of a token, yours will look probably a bit differently but you get the idea I hope. Use Postman to see what's coming back in the token
There are a number of concepts to be understood when it comes to OAuth2, it does require a bit of research and practice.
In short, you request a token with A Basic Authorisation Header, you get the token back and it's telling you what type it is, in my case it's Bearer so that's my next Authorisation Header for any call to a protected resource.
My suggestion is to start small, one step at a time, use Postman to build your calls and understand what's going on. Once you have that knowledge it's much easier to progress. Took me about 6 weeks to wrap my head around all concepts and get something working first time around, but now it takes a couple hours at most. Good luck
The application does not need to store the access token server side, it will only read the user from the token which is passed along.
When the request hits the authentication server, which is attach to the Owin pipeline in the ConfigureOAuth() method,
the HTTP header token is decrypted and the user data from the token is sat to the current user of the context.
This is one of the things that bugged me for a long time
I'm not sure I understand why did you give an example for 2 applications, but the token mechanism is actually simple, but it's kinda black boxed when you use owin and identity
the token is not stored anywhere on the server or the database, authenticating the user on login is done using your logic or usually again black boxed in identity, this involves validating a secured password etc
after this the token is generated (usually using identity) or if you did it manually this will involve securing the token with whatever info you want to store in it
when the user sends a request next time he should pass the token and you will need to decrypt it and validate what's necessary (like expiration time for example), all of this is done behind the scene usually
just a fun note: even if you changed the DB completely the token will still be valid with the user id that doesn't even exist in your new DB! but of course identity automatically invalidates this token when it compares with the securityStamp

ASP.NET C# Get Facebook user details

I start to working with the Facebook graph API and I have question:
I make Facebook Authentication, so after user approve my application I got accessToken and the facebookUserID. note: The accessToken is expire after One hour(!!!).
Then, in another webpage "index.html", I want to show all the users who approved the application with their full name and profile picture taken from Facebook.
Now I don't understand.. if someone will enter the "index.html" page to see list of users who accepted the application - 5(!!) month after their authentication, when i will make the HTTP call to get thier fullname and profile picture, the accessToken is now expire(a lot time before) so the HTTP call will not succeed.
The last option is to save the full name just in the One hour between user accept the application and before the accesstoken expiration. but if the user will change his name sometime... I don't have the updated Name!
if its important - I'm usind the javascriptSDK with asp.net project.
Please help me to understand how to solve this situation.
It would appear that it is not possible to generate a long-lived token with the JS SDK directly, you will have to involve the server side, see this page for details.

C# GMAIL API Service Account Modify - unauthorized_client

I am just starting out with the c# Google.Apis.Gmail.V1 classes and using a service account to read a mailbox.
My code works fine when I use the following snippet
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountEmailAddress)
{
User = "abc#test.domain.com",
Scopes = new[] { "https://www.googleapis.com/auth/gmail.readonly" }
}.FromCertificate(certificate));
With that code I can call the following successfully
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
}
But I need to modify the email messages so I changed the scope from
https://www.googleapis.com/auth/gmail.readonly
to
https://www.googleapis.com/auth/gmail.modify
I now get an exception when requesting the access token
{"Error:\"unauthorized_client\", Description:\"Unauthorized client or scope in request.\", Uri:\"\""}
I have checked the service account (*.iam.gserviceaccount.com) in the Google Developers Console and I have tried all options for permissions including OWNER which should give me Full access to all resources but no joy.
I think I am just missing a simple step but I am unsure of where to look next.
TL;DR
I would read through this, but here is the short version. I know this is an older post, but hopefully it finds you!
If you have not updated/white-listed the service account's privileges/scopes in the Google Admin Console you will need to do that, make sure the domain has API access enabled, make sure the service account is setup properly, when creating the "certificate" object be aware its parameters so that it is being instantiated correctly, check the permissions on the account being impersonated and finally make sure you've made an appropriate Google Apps service account key (could have easily made an inappropriate key type.)
White-listing Google APIs in the Admin Console
This gives the Google Apps service account the abilityto use whatever scopes you provide in your Google Apps domain.
Login to the Google Apps Admin Console by using the following link.
https://admin.google.com/
The Google Apps user account must have sufficient privileges to modify domain related settings. It does not have to be the account used to create the Google Apps project in the developer console. If the account does not have privilege you will be directed to a completely different screen with no options to click on varying domain controlling web apps like "Security", "Roles", "Support", "Groups" and etc. Instead you'll dumped onto a page that shows things like "Gmail", "Drive", "Docs" and etc. that is typical user apps. The current link it drops you at is https://apps.google.com/user/hub
Click “Security.”
Click “Show more” option at the bottom of the security options list.
Click “Advanced Settings” to get the more options.
Select the “Manage API client access” link.
Now certain API scopes must be white-listed for the desired service account. In the “Client Name” text box provide the service account’s client ID. The client ID is obtained in the developer console. In the “One or more API scopes” add the desired scopes; comma delimited.
Note, if there are existing scopes they will be removed so be sure to re-add any that will be needed.
Enable Domain Wide API Access
Login to the Google Apps Admin Console by using the following link.
https://admin.google.com/
Go to the “Security” page.
Under “API reference” section
Make sure that “Enable API access” is enabled.
Creating an Appropriate Google Apps Service Account Key (Probably this)
Go to the Google Developer Console. Login as the Google Apps user that created the Google Apps project/service account. https://console.developers.google.com/
Navigate to the particular project with which you created the service account.
Click the "Service Account" button on the left of the project's page to bring up a page with all of the project's service accounts.
Click the vertical ellipse widget all the way to the right of the desired service account's row. Select “Create Key.”
Select .p12 key as it looks like this is what you're trying to use. Click "Create." Be sure to protect this key.
I have found that if the key is not created this way then it leaves open the possiblity for making either an API key or an OAuth 2.0 client/user key. These are the wrong types of keys to use in this case you would need to have created a service account key. The way outlined above forces you to create a service account key.
Modifying the Existing Google Apps Service Account's Settings
I'm not going over how to setup the actual service account, one thing you may need in your case is to make sure that the service account has domain wide delegation enabled. This is toggled in the Google Developer Console. Should be pretty easy to find.
Code
You do not provide your entire code base for creating the token, so just want to add a few things you might be doing improperly.
Make sure when you create the certificate that the secret you provide is the default "notasecret" string. This secret is currently the default value provided by all keys distributed by Google and is immutable during key creation. I had a link to prove this, but have since lost it.
X509Certificate2 certificate = new X509Certificate2(certificateFilePath, "notasecret", X509KeyStorageFlags.Exportable);
Just trying to advocate proper coding. While I have found some bugs in the past with Google's constant values that required additional string manipulation (adding additional slashes.) You should really be using the string constants that they provide in place of literals. I only say to use these because it provides a layer of abstraction, who is to say Google will never change the literal; unlikely.
In your case the new scope is:
GmailService.Scope.GmailModify
While the old scope was:
GmailService.Scope.GmailReadonly
Otherwise, everything code wise looks good to me.
Another thing to try would be to make sure that the actual Google Apps user account being impersonated by the service account has sufficient privileges. I would suspect a different error if this were the case, would be getting a 403 in the response instead. Anyway, in your case this is the "abc#test.domain.com" account. Once again you would go to the Google Admin Console, check its roles make sure it has sufficient roles checked for whatever it is you're trying to do. I don't know what specifically you'll need in this case, best bet would be to give it the same permissions as the "Super Admin" role then remove permissions as you go to see what it might actually need. Otherwise, if possible just give it "Super Admin."
If I was a gambler I would put my money on an inappropriately created service account key. I just recently ran into this and it was the only thing that produced the same exact error you're receiving. Other things would get me the same "Description" value in the response token, but not the same "Error" value. I'm not really even sure how the culprit key was made, because I didn't make it. I just know the fix was to recreate a new key with the steps above and that fixed the issue.

Categories

Resources