Authorizing Google service account with JWT for Gmail API - jwt

I am trying to access my emails through Gmail API (through AWS lambda), using service account credentials. I do not have a GSuite account, so I cannot delegate domain-wide authority and impersonate my user#gmail.com account.
I resorted to Service account authorization without OAuth, using a signed JWT directly as a bearer token. [see]: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth
I also enabled all access to Gmail to the application and made service account an owner role in the console.
I am using google.auth.jwt module, but struggle to understand the documentation fully: [see docs]: https://google-auth.readthedocs.io/en/latest/reference/google.auth.jwt.html#module-google.auth.jwt
This is what I tried:
from googleapiclient.discovery import build
from httplib2 import Http
from google.auth import crypt
from google.auth import jwt
audience = 'https://mail.google.com/' ## full access scope
credentials = jwt.Credentials.from_service_account_file(
'credentials.json', audience=audience) # json credentials from api console - for service account
service = build('gmail', 'v1', credentials=credentials)
This gives me a 401 error:
googleapiclient.errors.HttpError: <HttpError 401 when requesting https://www.googleapis.com/gmail/v1/users/me/messages?alt=json returned "Invalid Credentials">
credentials object return appears as valid, with all necessary elements, however, I don't know how to make it "impersonate" my personal email.

Invalid credentails normally means that the credentials.json is not the correct type for the code you are using.
Make sure that you have downloaded the credentials.json for a service account.

Related

is there an admin API for keycloak to get the OIDC installation JSON

I have tried this URL : http://lists.jboss.org/pipermail/keycloak-user/2018-September/015665.html, though with no help.
i have an access token to call admin API's
Xtreme Biker is right.
I could get the url from UI console.
/realms//clients//installation/providers/keycloak-oidc-keycloak-json
using client name, client-id can be retrieved using endpoint
/auth/admin/realms/${realm}/clients?clientId=
The catch is the access token that has to be supplied to the admin endpoints to respond successfully.
Access token shall be retrieved using a credentials of a user who has 'manageclients' access to the client role of the realm under which the client is registered.

Google Cloud storage: Grant permission to OAuth 2.0 client

I try to download a file from a google cloud drive bucket via the REST. But if I use the access_token of the oAuth 2.0 client which I have created I get "Insufficient Permission" as an error (It works with the access toke of my googel account).
So, where in the cloud platform I can grant the oAuth2 client access to the bucket from where I want to download the file?
Thx
TL;DR - You're most likely missing the step where you request the right scopes when requesting your OAuth2.0 access token. Please look at the supported scopes with Google Cloud Storage APIs. Access tokens typically expire in 60 minutes and you will need to use a refresh token to get a new access token when it expires.
Please read the Google Cloud Storage Authentication page for detailed information.
Scopes
Authorization is the process of determining what permissions an
authenticated identity has on a set of specified resources. OAuth uses
scopes to determine if an authenticated identity is authorized.
Applications use a credential (obtained from a user-centric or
server-centric authentication flow) together with one or more scopes
to request an access token from a Google authorization server to
access protected resources.
For example, application A with an access
token with read-only scope can only read, while application B with an
access token with read-write scope can read and modify data. Neither
application can read or modify access control lists on objects and
buckets; only an application with full-control scope can do so.
Authentication in Google Cloud
Google Cloud services generally provides 3 main modes of authentication:
End User Account credentials - here you authenticate as the end user directly using their google account or an OAuth 2.0 access token. When requesting an access token, you will need to provide the scopes which determine which APIs are accessible to the client using that access token.
OAuth2.0 credentials - if granted the right scope, can access the user's private data. In addition, Cloud IAM lets you control fine grained permissions by granting roles to this user account.
Service Accounts - here you create a service account which is associated with a specific GCP project (and billed to that project thereby). These are mainly used for automated use from your code or any of the Google Cloud services like Compute Engine, App Engine, Cloud Functions, etc. You can create service accounts using Google Cloud IAM.
Each service account has an associated email address (you specify when creating the service account) and you will need to grant appropriate roles for this email address for your Cloud Storage buckets/objects. These credentials if granted the right roles can access the user's private data.
API keys - here you get an encrypted string which is associated with a GCP project. It is supported only by very few Google Cloud APIs and it is not possible to restrict the scope of API keys (unlike service accounts or OAuth2.0 access tokens).

GSuite : Client is unauthorized to retrieve access tokens using this method

Hi I'm trying to develop an for GSuite admin which enables to migrate their google drive data to another cloud service. But in the process of authentication i'm getting the below error.
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method."
}
Below are the api's that are enabled in developer console.
1. Admin SDK
2. Contacts API
3. G Mail API
4. Calendar API
5. Drive API
Please guide me if done anything wrong in creating an app.
The main thing what i missed here is Authorizing my service account client ID with the GSUITE admin.
And I have been trying to generate access_token for the expired domain of mine.
After clearing all these i have to success in generating and getting user data.
This solution worked for me. I hope it works for you tooo....
Thank you community.

What Authorization token is required for Google Cloud Storage JSON API?

I am learning Google Cloud Storage, the JSON api, simple upload:
https://cloud.google.com/storage/docs/json_api/v1/how-tos/simple-upload
The example says to send a post looking like this:
POST https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=media&name=myObject HTTP/1.1
Content-Type: image/jpeg
Content-Length: [NUMBER_OF_BYTES_IN_FILE]
Authorization: Bearer [YOUR_AUTH_TOKEN]
[JPEG_DATA]
And then I created a "Service accounts" API.
But how do I figure out the [YOUR_AUTH_TOKEN] to use from my newly created Service account?
Google Cloud uses OAuth 2.0 to handle authentication. There are a variety of techniques for generating a token depending on your needs. If you're writing a program using one of Google's client libraries, the details are mostly taken care of for you. Google has a lengthy guide on the nitty-gritty: https://developers.google.com/identity/protocols/OAuth2
You are looking to authenticate as a service account. Service accounts generally authenticate by creating a token request document called a JWT, signing it with a private key associated with the service account, then exchanging the JWT with Google for a token. This process is described over here: https://developers.google.com/identity/protocols/OAuth2#serviceaccount
From your desktop, if you want to auth as a service account, one easy way is to use gcloud to authenticate as a service account and then ask it for a token:
$> gcloud auth activate-service-account myaccount#gserviceaccounts.com --key-file=creds.json
$> gcloud auth print-access-token

Oauth2: how should the resource server know if the access token is valid?

I'm implementing an Ouath2 authentication with Spring for our mobile API. So far it works but I don't know how I should keep the resource server separate. So I have an auth server which gives out tokens and refresh tokens using the password grant-type. Meaning the user would log into the mobile app, which sends the auth server the client id/client secret along with the user's
credentials, which results in an access token and a refresh token for the user with the appropriate (ROLE_USER) privileges. Another web based client is for the admins who do the same and get the ROLE_ADMIN privilege etc.
This works well so far.
Now if any client sends a request to the resource server what should happen? Should the resource server check the token's validity? If so in what way? Or should the auth server copy the token into the resource-server's database?
If you #EnableResourceServer you get a filter that checks access tokens. It needs to share a TokenStore with the auth server. That's about it to get something working.