GSuite Marketplace app with Service Account - google-api

Trouble getting Service Account authorized for Marketplace app
In the process of publishing our app, we require two types of consent:
Directory-wide consent by an admin for SSO, on behalf of all users ("https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile").
Domain-Wide authority of https://www.googleapis.com/auth/calendar.events
The credential type we are using for 1 is OAuth Web ClientId, since there is a browser-based user login. The credential type we are using for 2 is Service Account, since we want to read calendars offline.
The problem is when the app is installed from the marketplace, only the OAuth WebClientId is added to "Authorized API clients" in the installer's Gsuite Admin portal. The service account is not added, and therefore doesn't get access.
What is the solution?
We tried "Enable Domain-Wide authority" on the Service Account, it did create an OAuth Web ClientId, but it does not allow for setting up redirect URLs.

Apparently we already had access via the service account - it is not necessary for the service account client_id to appear in Authorized API Clients"
As long as
1) You enable "domain-wide authority" on the service account
2) The App project is the same project as the service account
It should work

Related

Google Workspace marketplace service account for public listing

I have a server-side application that needs to access every user's gmail data in a google workspace organization. I want to publish a public listing on the google workspace marketplace that is installable domain-wide by the super admin user and gives the server-side application the permissions to access the gmail data of the user's in that domain.
From my current understanding, we need a service account with impersonation to access each user's data. On top of that the service account needs to be delegated domain-wide authority, so that user's do not need to give individual OAuth consent or their passwords.
When publishing the app using the marketplace SDK I see that there is a field for service account credentials:
I see that the current Marketplace SDK has a field that accepts service account credentials.
But when my app is published and I install it and go to check the app's data access. I can only see fields for the scopes and the Oauth clients.
My questions:
Are the service accounts created in the marketplace SDK usable to the organization that installs my marketplace app? Will the service account's have the same email and unique id for everyone who installs the public listed app?
If (1) is not true, then how is it possible for admins to create a service account for my marketplace app?
If (1) is true, is it automatically granted access unlike the OAuth clients and scopes?
If (1) is true, Are the service accounts automatically delegated domain-wide on install or do we have to provide the person who installed the marketplace app with the service accounts unique ids so they can manually delegate the scopes domain-wide.
I reviewed some Google public documentations related to Service Account & here’s what I have found that may answer your questions:
Question 1
Are the service accounts created in the marketplace SDK usable to the organization that installs my marketplace app?
Answer
No
Note: The CREDENTIALS tab that you see on the Google Workspace Marketplace SDK page is only an overview of credentials you have created for the GCP Project & NOT necessarily only for that service/API.
Service Accounts are created within a specific GCP Project & that project is where you will enable the Google APIs/Services that your application needs. Google Workspace Marketplace SDK is being described as:
“A toolkit that lets you create and control your app listing on the Google Workspace Marketplace, or for Chat apps, in Google Chat.” (Source)
So, this Google Workspace Marketplace SDK doesn’t necessarily use a Service Account to authenticate & be called in your app. However, when you setup a Service Account for your app, you'll need to create a Google Workspace Marketplace OAuth Client & this OAuth Client is associated to that Service Account. This is needed to support Google Workspace Marketplace domain-wide installation.
Setting up the Google Workspace Marketplace OAuth Client from the GCP console:
Follow-up Question
Will the service account's have the same email and unique id for everyone who installs the public listed app?
Answer
Yes. In theory, it should be.
Question 2
If (1) is not true, then how is it possible for admins to create a service account for my marketplace app?
Answer
You have to review the official Google documentation for OAuth & Service account.
Based on the official documentation, this is the overview:
Create a service account for your project
Delegate domain-wide access to the service account
Your application prepares to make authorized API calls using the service account's credentials. (This is regardless of how many users install & use your app)
That API call will request an access token from the OAuth 2.0 auth server.
Your application will then be able to use the access token to call Google APIs (which in your case uses Gmail API).

Google ClassRoom OAuth Integration Spring Boot

I am creating a web application with Spring Boot and JSF and my intention is to create courses in google classroom from my application.
I followed the example of Google to authenticate myself by Oauth: https://url.miapp.io/oS2mx
Implement that ClassroomQuickstart class from the example, but when you use the method getService() in my web application, it sends me in the Tomcat Embeded Console (Spring Boot) a Google URL for authenticate by myself from a browser and I can continue with the flow of my code.
In other words, authentication works in interactive mode waiting for me to authenticate from the browser so the application can continue the execution flow, I don't know what I should do so that I don't have to authenticate myself in this way, I don't know if it's the code that implements it as it is or has to do with the configuration in the google developer console.
3-legged OAuth:
You are currently following a 3-legged OAuth process, in which there are three parties involved: (#1) end-user, (#2) application and (#3) authorization server. In this OAuth flow, users need to give explicit consent to the application through the browser via a consent screen.
2-legged OAuth:
Since you want to avoid that, you should use a service account to access this application, so that users are not directly involved and user consent is not required. This workflow is usually called 2-legged OAuth (only the application and the authorization server are involved). See Using OAuth 2.0 for Server to Server Applications for a more in-depth explanation.
Since you don't want the service account to run the application by itself, but to act on behalf of other accounts in the domain, you should grant it domain-wide authority so that it can impersonate other accounts in the domain.
Workflow:
To achieve this, you have to follow these steps:
Create a service account by following this guide.
Delegate domain-wide authority to the service account (you have to be a domain administrator to do this): this step authorizes the service account to access data on behalf of any user in the domain. Follow the steps indicated here.
Once you have delegated domain-wide authority, you have to modify the code related to the building of the OAuth credentials. Use, for example, the code sample provided in this answer:
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("service-account#email-address") // Service account email
.setServiceAccountPrivateKeyFromP12File(new File("your-credentials.p12"))
.setServiceAccountScopes(Collections.singleton(ClassroomScopes.CLASSROOM_COURSES))
.setServiceAccountUser("user#email-address") // Your email address (address of the user you want to impersonate)
.build();
In this case, user#email-address refers to the account on behalf of which the course should be created. In order words, it will be the account that the service account should impersonate. Regarding theP12 file, it should be downloaded from the Cloud Console, as explained here. This can be done with a JSON file instead of P12 (see here).
Reference:
Using OAuth 2.0 for Server to Server Applications

Office365 Exchange REST API errors, endpoints and permissions issues

I am trying to understand the API's that #Microsoft provides. Its just so messy. My goal is to use the Exchange API to edit settings.
So, I have an APP, Access tokens and subscriptions.
When trying to login to https://outlook.office365.com/ I get the following error:
Your subscription is no longer active. Please contact your admin to activate your subscription.
X-ClientId: 05A0A74F610C432EA1AD48C77829580B
request-id 3088673c-f523-4e26-824f-1d0f7cb0a219
X-OWA-Error Microsoft.Exchange.Data.Storage.TenantAccessBlockedException
X-OWA-Version 15.20.2451.30
X-FEServer HE1PR05CA0360
X-BEServer HE1P190MB0508
Date:18/11/2019 09:11:34
But as you can see, I have a subscription:
What I understand is that I have to login to outlook.office365.com before using the API.
Update
Ok, so I can now login to https://outlook.office365.com/mail/inbox. It took a while............. But;
1) I can request: https://outlook.office365.com/api/beta/users/********************************/. It will return the specified user.
2) I can NOT https://outlook.office365.com/api/beta/users/********************************/mailfolders. I tells me 'access denied'. While my app has all Exchange, Office365 permissions. But delegate and application permissions.
The "Grant admin consent for your tenant" feature seems to have been updated yesterday.
However, something is wrong with the new "Grant admin consent for your tenant" feature based on my test.
If you use it to grant admin consent, it will probably not take effect on the back end although admin consent has been successfully completed on Azure Portal.
Currently you could grant admin consent through a URL request.
https://login.microsoftonline.com/{your tenant}/oauth2/authorize?client_id={app id of your Azure AD app}&response_type=code&redirect_uri={redirect uri of your Azure AD app}&nonce=1234&resource=https://outlook.office365.com/&prompt=admin_consent
Please note that you need to create a new Azure AD App currently because if you have used admin consent on Azure Portal, granting admin consent through a URL request will not take effect.

send emails from MY gmail account with OAuth2 and nodemailer

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.

Google Apps Marketplace Application Using Service Account

I have attempted to publish an application to the Google Apps Marketplace that uses a service account to act on behalf of users within a domain. How does the installation flow differ based on whether the installing user is an administrator or a normal user since it requires the service account to be authorized in the Google Admin console?
I am getting push back during the application review asking why the app is requiring an admin to manually authorize the API scopes for the service account in the Google Admin Console. If a Google Apps Administrator installs the application for the domain and consents to all of the application access, does that authorization apply for all users in the domain? I do not want all users in a domain to be prompted with the OAuth 2 consent screen.

Resources