I'm trying to open a file that needs an authorization token for the request, using the cloudstorage api.
Using a token previously defined: 'access_token', my code looks like this:
gcs_file = gcs.open(file_path, 'w', options={'Authorization': access_token})
The problem is that I'm getting the following error:
option Authorization is not supported
I guess that I'm not opening this file properly.
Does someone know how should I invoke this function with the token?
Thanks a lot!
You can access buckets and objects that don't belong to your project, so long as your app's service account has been granted access. If you have literally been handed a valid OAuth 2 access token and want to use that, you could use the Google API Python Client, which can use the oauth2client.client.AccessTokenCredentials class to authenticate with an access token.
I'm curious, though. Where did your app get ahold of an access token and why do you want to use it?
Related
I am building a local desktop app where I can read, classify, and create playlists.
The following auth code I have is:
##oauth
scope = "playlist-modify-public playlist-read-private playlist-modify-private"
sp = spotipy.Spotify(
auth_manager=spotipy.SpotifyOAuth(
client_id=client_id,
client_secret=client_secret,
redirect_uri= "https://example.com/callback/",
scope= scope, open_browser=False))
when run on cmd, this asks to click the link generated and then to paste the link that I was redirected to. I want to know if there is another way to provide authorization (automatically or permanently) so that my .exe app doesn't run into an error.
code in your response would help a lot.
You cannot grant permanent access to the APIs in a single call, but you can refresh your token automatically whenever the access expires, as shown in the docs.
If you're using Python, I recommend to do this via Spotipy, which makes the auth process much easier (see https://spotipy.readthedocs.io/en/master/#authorization-code-flow)
I only want to pull data from a list called dataacq within a group (or site?) called prod within the domain (or root site?) tenant.sharepoint.com (or tenant-my.sharepoint.com ?) and put it into a DataFrame.
I have an issue with the token gotten through app.acquire_token_silent.
Microsoft documentation is not comprehensible because it's too heavy and has little workable cookbooks/working examples (as can be seen by my numerous question marks). Also it seems they want to centralize all their APIs into graph.microsoft.com, yet there is no warning that tenant.sharepoint.com/sites/prod/_api/ is going to be discontinued.
I have gotten the following permissions from the azure portal for my app.
I don't believe I need all of them, but I am not sure. I just want to read a list. So is only Microsoft Graph > Sites.read.All necessary? Or is it Sharepoint > Allsites.Read ?
I know I both have an "app only" permission and a "signed in user" permission.
I did download the "quickstart" examples and I did read https://msal-python.readthedocs.io/en/latest/ . Although a token was successfully pulled using app.acquire_token_silent, using the returned token always throws some error whatever scope ('https://microsoft.sharepoint-df.com/.default' or 'https://graph.microsoft.com/.default') or API domain (graph.microsoft.com or tenant.sharepoint.com) I am using into a request:
{'error_description':
"Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown."}
{'error': {'code': 'AccessDenied',
'message': 'Either scp or roles claim need to be present in the token.',
'innerError': {'date': '2021-02-19T08:05:16',
'request-id': '01efc071-18e6-4006-8780-f771419ebe3e',
'client-request-id': '01efc071-18e6-4006-8780-f771419ebe3e'}}}
On the other hand, there is an API developer testing portal. When I am copying the token given in this portal into my python code, both scope/API domains work.
This is e.g. an example that works with copying & pasting the token from the portal, but not working with the token issued by the app.acquire_token_silent method:
r = requests.get( # Use token to call downstream service
fr'https://graph.microsoft.com/v1.0/sites/root:/sites/prod:/lists/{list_id}/items?expand=fields(select=Created))',
headers={'Authorization': 'Bearer ' + result['access_token'],},)
So the issue is with this app.acquire_token_silent method or the configuration file. But the returned response seems alright:
{'token_type': 'Bearer',
'expires_in': 3599,
'ext_expires_in': 3599,
'access_token': '...'}
What am I missing?
According to the code r = requests.get..... you provided in your description, it seems you use the microsoft graph api to implement it. If you use this api, you should use https://graph.microsoft.com/.default as scope to get the access token. And you can copy the access token to this page, decode the token and check if the permissions are included in it.
And according to the screenshot of "API permissions" tab of your registered app, please also do grant admin consent operation for the permission Sites.Read.All although it shows not required admin consent.
================================Update===============================
It seems the method acquire_token_silent() acquire the access token by client credential flow. So we should add the "Application" type permission but not "Delegated" permission in registered app.
What is the python programmatic alternative to the gcloud command line gcloud auth print-identity-token?
I am trying to invoke Google Cloud Function by http trigger (only for auth users) and i need to pass the identity token in the Authentication header. I have method which works great when i run the code on GCP app engine. However, i struggle to find a way to get this identity token when i run the program on my own machine (where i can create the token with gcloud command line gcloud auth print-identity-token)
I found how to create access-token according to this answer but i didn't managed to understand how can i create identity-token.
Thank you in advance!
Great topic! And it's a long long way, and months of tests and discussion with Google.
TL;DR: you can't generate an identity token with your user credential, you need to have a service account (or to impersonate a service) to generate an identity token.
If you have a service account key file, I can share a piece of code to generate an identity token, but generating and having a service account key file is globally a bad practice.
I released an article on this and 2 merge requests to implement an evolution in the Java Google auth library (I'm more Java developer that python developer even if I also contribute to python OSS project) here and here. You can read them if you want to understand what is missing and how works the gcloud command today.
On the latest merge request, I understood that something is coming from google, internally, but up to now, I didn't see anything...
If you have a service account you can impersonate this is one way to get an ID token in Python from a local/dev machine.
import google.auth
from google.auth.transport.requests import AuthorizedSession
def impersonated_id_token():
credentials, project = google.auth.default(scopes=['https://www.googleapis.com/auth/cloud-platform'])
authed_session = AuthorizedSession(credentials)
sa_to_impersonate = "<SA_NAME>#<GCP_PROJECT>.iam.gserviceaccount.com"
request_body = {"audience": "<SOME_URL>"}
response = authed_session.post( f'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{sa_to_impersonate}:generateIdToken',request_body)
return response
if __name__ == "__main__":
print(impersonated_id_token().json())
I am evaluating different options for authentication in a python App Engine flex environment, for apps that run within a G Suite domain.
I am trying to put together the OpenID Connect "Server flow" instructions here with how google-auth-library-python implements the general OAuth2 instructions here.
I kind of follow things up until 4. Exchange code for access token and ID token, which looks like flow.fetch_token, except it says "response to this request contains the following fields in a JSON array," and it includes not just the access token but the id token and other things. I did see this patch to the library. Does that mean I could use some flow.fetch_token to create an IDTokenCredentials (how?) and then use this to build an OpenID Connect API client (and where is that API documented)? And what about validating the id token, is there a separate python library to help with that or is that part of the API library?
It is all very confusing. A great deal would be cleared up with some actual "soup to nuts" example code but I haven't found anything anywhere on the internet, which makes me think (a) perhaps this is not a viable way to do authentication, or (b) it is so recent the python libraries have not caught up? I would however much rather do authentication on the server than in the client with Google Sign-In.
Any suggestions or links to code are much appreciated.
It seems Google's python library contains a module for id token validation. This can be found at google.oauth2.id_token module. Once validated, it will return the decoded token which you can use to obtain user information.
from google.oauth2 import id_token
from google.auth.transport import requests
request = requests.Request()
id_info = id_token.verify_oauth2_token(
token, request, 'my-client-id.example.com')
if id_info['iss'] != 'https://accounts.google.com':
raise ValueError('Wrong issuer.')
userid = id_info['sub']
Once you obtain user information, you should follow authentication process as described in Authenticate the user section.
OK, I think I found my answer in the source code now.
google.oauth2.credentials.Credentials exposes id_token:
Depending on the authorization server and the scopes requested, this may be populated when credentials are obtained and updated when refresh is called. This token is a JWT. It can be verified and decoded [as #kavindu-dodanduwa pointed out] using google.oauth2.id_token.verify_oauth2_token.
And several layers down the call stack we can see fetch_token does some minimal validation of the response JSON (checking that an access token was returned, etc.) but basically passes through whatever it gets from the token endpoint, including (i.e. if an OpenID Connect scope is included) the id token as a JWT.
EDIT:
And the final piece of the puzzle is the translation of tokens from the (generic) OAuthSession to (Google-specific) credentials in google_auth_oauthlib.helpers, where the id_token is grabbed, if it exists.
Note that the generic oauthlib library does seem to implement OpenID Connect now, but looks to be very recent and in process (July 2018). Google doesn't seem to use any of this at the moment (this threw me off a bit).
My project is python and using boto3 lib.
I'm using aws cognito Authorization code grant flow with return_type=code instead of return_type=token (implicit flow). Once my user is authorized my redirect url is injected with the queryStringParameter code=4d55a121-8ffc-4058-844b-xxxx.
outlined here
I need to be able to verify this code. Because of course someone can take the redirect url and make a fake code and paste it into the browser. According to this doc I can exchange the code for a token. This works as expected via a rest client. I get the token and can continue to pass the token as the Authorization header. But what I'm asking is there has to be a boto3 method that takes this code and converts it into a token for me. If i have to use the requests lib I will.
I have tried for days. get_user isnt the answer as that requires a token not the code.
For reference on what I'm trying to do heres my repo. The focus is in def edit(). I'm currently using requests to achieve the same thing but would like to use the boto library
https://github.com/knittledan/python-lambda-cognito
Nope, believe you should use an https client to exchange the authorization code for tokens with the token endpoint provided:
https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html