We are working on a serverless document manager using AWS.
Is it possible to integrate DocuSign embed-UI (link below) with JWT token by just using Lambda & other serverless components via Node.js?
https://developers.docusign.com/docs/esign-rest-api/how-to/embed-ui/
Or is there any Angular JS solution that we can integrate completely on the frontend?
I think your question is:
Single page app front end (React / Angular / etc) with a serverless backend (AWS Lambda)
How to authenticate with DocuSign so the signing ceremony can be shown on the front end?
The signers on the front end do not have DocuSign accounts--as signers they don't need such accounts.
Answer
Because of issues 2 and 3, JWT grant is the way to go. The overall application will impersonate a system user such as doc_manager#example.com. That system user will be used to obtain the embedded signing ceremony URL from the DocuSign API.
Can JWT grant be managed by Lambda functions?
I haven't tried, but I think it should work ok:
When a Lambda func needs a DocuSign access token it would look in stable storage for an access token that hasn't expired (a database or other storage that is maintained across Lambda invocations). Access tokens from JWT grant last an hour.
If an access token is available, it is used. END
If an access token is not available or expired, the Lambda would initiate the JWT grant flow. That takes a couple of seconds.
The resulting access token is stored in the stable storage and is used by the function to call the DocuSign API. END
Notes:
If the app will be using multiple DocuSign user accounts, then the app will maintain multiple access tokens, one per impersonated user/account.
Don't create a new access token unless the old one is near (within 10 minutes) its expiration or has expired. There are limits on the number of outstanding access tokens, plus the JWT grant flow is slow.
Since the access tokens represent user access, safeguard them appropriately!
The front end
When the URL for the DocuSign signing ceremony is received from the back end, either redirect the browser to the URL, or open a new tab to the URL. Don't use an iFrame.
Related
I have a web app which sends emails (gmail) in name of my users
When a user registers, she supplies gmail account and password. Also she has to enable access for Less Secure Apps (I recommend to create a new account for this)
Then I can open a gmail session
session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getEmail(), user.getPassword());
}
});
and send emails on her behalf.
Unfortunately this is going to stop working next 30th May, when Google will allow only OAUTH2 access
I have followed Java Quickstart for Gmail API and I have code up and running for sending emails with OAUTH2: enable gmail api, create an application on google cloud platform, grant send permission, oauth2 client id credential created...
The problem I have is I can't see a way to automatize this task because when creating an authorized credential, a consent screen displays on browser and you have to select the account to be granted manually (maybe because my app in google cloud platform is still pending to be reviewed)
Is there a way to infer the gmail account you want to access from the credentials file (client_secret.json)? Is there a way to automatize this?
No, or yes. It depends.
The whole point of OAuth2 is to improve security by working with authorization tokens rather than asking for user credentials. To do this the user has to consent to the app's access request, and thus the OAuth consent screen cannot be bypassed. This is
explained in Google's documentation. It's not related to your app's review status but rather it's the way OAuth works.
You can still work in a similar way, though . Instead of asking for username and password upon the user's registration you can redirect them to the OAuth consent screen so they can authorize your app. Make sure that your app is requesting offline access type and then you can retrieve an access_token and a refresh_token. These will essentially work as your credentials and you can use the refresh token to generate new access tokens when needed without having the user go through the consent screen each time.
The refresh token doesn't have a "natural" expiration so you can keep using it indefinitely, but there are a few scenarios where it will become invalid, such as it not being used for six months, the user changing passwords (if using Gmail scopes), the user manually revoking access, etc. In these cases you will need to direct them to the consent screen again to reauthorize your app.
In this sense, your app can still work automatically without user input except the initial setup, which you already had to deal with when they supplied you with their credentials. The refresh token expiration can even be compared to what you had to do when the users changed their passwords in your current workflow.
One exception to this are service accounts. If you and your users are part of a Google Workspace domain you can delegate domain-wide access to it, then the service account will be able to access user data without any manual input. Of course, this is because as the domain administrator you pretty much own all the accounts under it. But if you're working with a publicly available application you will have to deal with the limitations I mentioned above.
Sources:
Google's auth overview
Using OAuth 2.0 to access Google APIs
OAuth 2.0 for web applications
The OAuth consent screen
I've found plenty of information on implementing Oauth2 using a user authorization step, but I'm trying to run a container that automatically scrapes a gmail inbox for attachments transforms them, and exports to prometheus, and I'm having trouble figuring out how to implement this library: https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config or any other for that matter to retrieve a token without involving a manual user step.
Will doing this in Go require writing direct API calls since I can't find an existing library to handle this scenario? Would it make more sense to create a Google App password and use generic user/pass SMTP authentication?
First off i understand what you are trying to do.
You have a backend system running in a container which will access a single gmail account and process the emails.
Now you need to understand the limitations of the API you are working with.
There are two types of authorization used to access private user data
service account - server to server interaction only works with workspace domains. No authorization popup required.
Oauth2 - authorize normal user gmail accounts, requires user interaction to authorize the consent screen
If you do not have a workspace account and this is a normal gmail user then you have no choice you must use Oauth2, which will require that a user authorize the application at least once.
Using Oauth2 you can request offline access and receive a refresh token which you can use to request new access tokens when ever you wish. The catch is that your application will need to be in production and verified, because your refresh token will only work for seven days and then it will expire. To fix this and get a refresh token that does not expire means that your application must in production and verified. This means you need to go though Googles verification process with a restricted gmail scope which requires third party security check and costs between 15k - 75k depending upon your application.
I understand that this is a single user system but that does not mean that you still need to go though verification. When google added the need for application verification they did not take into account single user systems like yours.
Option
Have you considered going directly though the SMPT server instead of using the Gmail api? If you use an apps password you should bypass everything by loging in using the login and the apps password.
I am creating a service where people will send emails to this one email account and this email account will regularly poll for new emails. The problem that I am having is that I will need to authenticate my email account and allow my service to call Google APIs to read it's mail box.
I was wondering if it would be alright to just authenticate myself once before deploying the service and then storing the access and refresh tokens in a database and then using those tokens to make the API calls. Are there any foreseeable problems such as the tokens expiring?
And if there are, do you have any suggestions on making API calls to the account without me having to login to the account to authenticate myself?
What you are wondering is correct. As you are getting a refresh token, you are asking for offline access which means you want make API calls on behalf of the user when is not present.
Access tokens have an expiration time, refresh tokens don't. However, there are some scenarios where refresh tokens could be revoked (and you need to handle them). So you have to use access tokens to make API calls and refresh tokens to generate new access tokens (when those have expired).
I will draw a scenario, and need some suggestions:
I'm using Azure AD (v1.0 endpoint), a single-page app (SPA) and a web API. The SPA establishes the user's identity using OpenID Connect, authenticates the user and receives an id_token and access_token for the back-end web API.
Now, we don't want the SPA to do access control decision based on the id_token received within the SPA app.
Instead, the SPA sends the access_token to the back-end web API to access it, and now we want back-end web API to make an access control decision based on the roles claim found in the id_token, but which the back-end does not receive from the SPA.
The question is, is it possible for the back-end web API to send received access_token to Azure AD token endpoint and receive the relevant id_token for the user so that the back-end web API receives an id_token containing the roles claims for the user, in order to make an access control decision?
There are a couple issues with the approach as you describe it:
The app roles would be defined on the native client application (the SPA). Though you can technically define app roles in the manifest, you'll notice the Azure portal won't let you assign users or groups to a native client app. (Which sort of makes sense, because, as you've rightly said, you don't want to do any access control in the native client app.)
You can't do what you've described (exchange an access_token intended for one audience, for an id_token intended for a different audience). There are some variants of token exchange which you can do, but none of them would help you in this situation.
Instead, what you should do is define the app roles on the web API. Then, assign the users to the corresponding app role for the web API. When these users sign in to the SPA, and the SPA gets an access token on their behalf to the web API, you'll notice the access token will contain the roles claim, populated with the appropriate values.
Summarizing:
Under App registrations for the web API, define your appRoles in the app manifest (or on the Application object directly, using (for example) Azure AD PowerShell).
Under Enterprise apps for the web API, assign users and/or groups to their corresponding app roles, and choose whether or not app role assignment is required or not*. (Or do so directly on the ServicePrincipal object.)
Under App registrations for the SPA (the Application object), add the web API as a required permission.
*If you choose to require app role assignment for the web API (under Enterprise apps > Properties), the SPA will not be able to get an access token for users who are not assigned to an app role for the web API. If you choose not to require app role assignment , users who are not assigned an app role will be able to sign in to SPA and the SPA will be able to get an access token on their behalf for the web API, but the access token will not contain a roles claim.
I want to send emails from my gmail address through my own server. I'm using nodemailer and using account credentials is flaky, and often times doesn't work and leads to this thread
I've implemented everything on that thread many times, and still it's flaky, and also I know OAuth2 is the way to go.
I have a project with cliendID and clientSecret in google developer console, as you can see:
But how do I get an access token WITHOUT any browser interaction?
I seem to be missing something trivial here ...
I've went through all google tutorials and docs I could find about OAuth2, tokens, and APIs, but all guides go through the browser in one point.
Go to the OAuth Playground, click the cog on the top right, check the Use your own OAuth credentials and insert your clientID and clientSecret.
Then select the Gmail API v1 scopes you want in the list to the left and follow the outlined steps and you will get an access_token and a refresh_token.
Google Oauth2 actually all Oauth2 implementations I am aware of require that a user grant an application access via a web browser.
There is an alternative type called service accounts this is more like oauth1 service accounts are preauthorized. You can grant a service account access to your google drive by sharing folders and files with the service account like you would any other user. Because they are preauthorized there is no browser window pop up with service accounts.
You can only user service accounts with Gmail if you have a Google domains account Gsuite. The admin can go in and grant the service account access to the Gmail account in question. Perform G Suite Domain-Wide Delegation of Authority
If this is a normal user Gmail account you cant use a service account. You will have to use Oauth2 popup the request and save the refresh token so that you can gain access at a later date.