Authentication and authorization on APIGEE using Python - python

I am trying to find a way to authenticate and authorize a client to access APIGEE. I can't seem to get it to function. I am using Python Requests-OAuthlib. Here is my code:
from requests_oauthlib import OAuth2Session
client_id = r'my_client_id'
client_secret = r'my_client_secret'
redirect_uri = 'https://api.usergrid.com/org/app'
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri)
authorization_url, state = oauth.authorization_url('https://api.usergrid.com/org/app/token', grant_type='client_credentials')
redirect_response = raw_input(authorization_url)
token = oauth.fetch_token('https://api.usergrid.com/org/app/token', client_secret=client_secret, authorization_response=redirect_response)
url = "https://api.usergrid.com/org/app/my_collection"
r = oauth.get(url)
I get an error: "Please supply either code or authorization_code parameters."
Any ideas on what I am doing wrong? I am using the APIGEE docs found here: http://apigee.com/docs/app-services/content/authenticating-users-and-application-clients
Thank you in advance.

Your client is sending response_type=code in the authorization request. That is why the server is not performing client credential Oauth.
This could be a default behavior of your python client. In that case you might want to use a simple http client to keep things under control.

Related

how to get id_token in Python Flask OpenID?

I have successfully implemented Keycloak OpenID + Python (v3.6) Flask integration using Flask-oidc.
I use below code to get user info,access_token and refresh_token
oidc = OpenIDConnect(app)
info = oidc.user_getinfo(['preferred_username', 'email', 'sub', 'given_name', 'iss'])
access_token = oidc.get_access_token()
refresh_token = oidc.get_refresh_token()
And got the results as well. But for a reason i need id_token as well. I tried,
oidc.get_cookie_id_token()
(which is already deprecated), but it gave decoded result not encoded token.
Anybody know how to get id_token from flask-oidc ?
I found a solution,
from oauth2client.client import OAuth2Credentials
id_token_jwt = OAuth2Credentials.from_json(oidc.credentials_store[info.get('sub')]).id_token_jwt

python oauth2 client issues when trying to get authorization token

I am trying to use OAuth2 to get an authorization token using Python to a REST API. I am successful doing so using CURL but not with python. I am using the examples provided at the following docs:
https://requests-oauthlib.readthedocs.org/en/latest/oauth2_workflow.html
The following is my code:
#!/usr/bin/python
import requests
import requests_oauthlib
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
client_id = 'AAAAAA'
client_secret = 'BBBBBB'
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url='https://example.com/as/token.oauth2', client_id=client_id, client_secret=client_secret)
print token
I am getting the following error:
oauthlib.oauth2.rfc6749.errors.InvalidClientError: (invalid_client) client_id value doesn't match HTTP Basic username value
This is a very basic API that only needs client_id and client_credentials to get an authorization token.
All information would be greatly appreciated.
The documentation specifies the following items:
client_id = r'your_client_id'
client_secret = r'your_client_secret'
redirect_uri = 'https://your.callback/uri'
By client key do you perhaps mean client key?
token = oauth.fetch_token(token_url='https://example.com/as/token.oauth2', client_id=client_id, client_secret=client_secret)
Try changing it to the above and give it a spin. using r'' for raw input instead and the token given.
I have found myself in a similar circumstance.
I am writing a Django app.
I was getting unauthorized_client and invalid_client exceptions.
In my case the post request in "Exchange the code" ("step 3" in the OAuth2 protocol) wasn't being formulated correctly.
Through much searching and trial and error I found it is possible to essentially customise the request. You can do this by specifying the optional arguments of auth, header and/or body.
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import WebApplicationClient, BackendApplicationClient
from requests.auth import HTTPBasicAuth
client_id = CLIENT_ID
client_secret = CLIENT_SECRET
authorization_base_url = AUTHORIZE_URI
token_url = TOKEN_URI
redirect_uri = REDIRECT_URI
auth = HTTPBasicAuth(client_id, client_secret)
scope = SCOPE
# Create the Authorization URI
# Not included here but store the state in a safe place for later
the_first_session = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url, state = the_first_session.authorization_url(authorization_base_url)
# Browse to the Authorization URI
# Login and Auth with the OAuth provider
# Now to respond to the callback
the_second_session = OAuth2Session(client_id, state=state)
body = 'grant_type=authorization_code&code=%s&redirect_uri=%s&scope=%s' % (request.GET.get('code'), redirect_uri, scope)
token = the_second_session.fetch_token(token_url, code=request.GET.get('code'), auth=auth, body=body)

How can I refresh a stored Google oAuth credential

I'm using the Python API that google provides. What I want to do is just make sure that the access token doesn't expire. I have the refresh_token stored in the credentials file. I'm just not sure how to 'check' that the token is still good before making the call to the API and if need be refreshing it and re-storing it in the credentials file.
I did a test that even if I delete the access tokens from the credentials file that it rewrites them into it using the refresh token. I'm hoping that will work for expired access tokens as well.
Thanks
storage = Storage('cred_storage.txt')
credentials = storage.get()
if not credentials:
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)
storage.put(credentials)
http = httplib2.Http()
http = credentials.authorize(http)
print http
service = build('admin', 'reports_v1', http=http)
print service
data_query = service.customerUsageReports().get(**{'date':'2015-01-07'})
feed = data_query.execute()
print feed
Simply check the case of expired access token and refresh your expired access token like this:
if credentials.access_token_expired:
credentials.refresh(httplib2.Http())
Tip: While developing this, you can test by editing the access token expiry date in the credentials text file and forcing it to be older than an hour
Also, in your code on the line where you are checking if not credentials:, you can better handle that case with:
if credentials is None or credentials.invalid:
I came across this question while trying to find a way to refresh an access token when construction a credentials object when using from_authorized_user_info. Unfortunately, the following code did not work for me:
credentials.refresh(httplib2.Http())
But I found this documentation from the Oauth library that works wonder. Shared below:
import google.auth.transport.requests
import requests
request = google.auth.transport.requests.Request()
credentials.refresh(request)

Google spreadsheets api do not use OAuth2?

I'm trying to make authorized requests to the google spreadsheets API and all the examples I found requests email and password from the user.
http://www.payne.org/index.php/Reading_Google_Spreadsheets_in_Python
http://www.mattcutts.com/blog/write-google-spreadsheet-from-python/
http://mrwoof.tumblr.com/post/1004514567/using-google-python-api-to-get-rows-from-a-google
Well this problem was solved with OAuth2 protocol which Google implements. I've gone through the OAuth2 process and I have a valid access_token, which I use to interact with Google Drive smoothly:
access_token = get_access_token() # external function
user_agent = request.META['HTTP_USER_AGENT']
credentials = AccessTokenCredentials(access_token, user_agent)
http = httplib2.Http()
http = credentials.authorize(http)
service = build('drive', 'v2', http)
service.files().copy(fileId=k, body=dict(title="Copia")).execute() # this works!
But I can't figure out a way to use the access_token to interact with the spreadsheets API. Does it still uses email and password login?
Thanks!
PS: BTW, I'm using the python gdata package, and please let me know if you have a good reference for it! :)
So, if you already have an access token (maybe you got it by your own via Oauth2 protocol, like me). You can interact with google spreadsheet api passing an instance of AuthSubToken to methods of SpreadsheetsClient.
from gdata.gauth import AuthSubToken
from gdata.spreadsheets.client import SpreadsheetsClient
atok = AuthSubToken(token_string=get_access_token()) # acess token via protocol
data = SpreadsheetsClient().get_worksheets(key, auth_token=atok)

Getting authenticationerror.login_cookie_required error while using Google adwords API with Python

I am trying to use python to consume some adwords soap API, I am able to get the auth token but when I try to make a get request I got the authenticationerror.login_cookie_required error. Any ideas?
from suds.client import Client
auth_data = {'accountType':'GOOGLE', 'Email':'xxx#xxx.com', 'Passwd':'xxxxxxxx', 'service':'adwords', 'source':'xxxxxxxxxx'}
auth_data = urllib.urlencode(auth_data)
auth_request = urllib2.Request('https://www.google.com/accounts/ClientLogin', auth_data)
auth_response = urllib2.urlopen(auth_request)
auth_response = auth_response.read()
split = auth_response.split('=')
auth_token = split[len(split)-1]
url = 'https://adwords-sandbox.google.com/api/adwords/cm/v201109/CampaignService?wsdl'
client = Client(url)
authToken = auth_token
developerToken = 'xxx#xxx.com++NZD'
userAgent = 'jameslin-python'
client.set_options(soapheaders=(authToken,developerToken,userAgent))
client.service.get()
Have you tried using the Python client library for the AdWords API?
http://code.google.com/p/google-api-ads-python/
authToken isn't a SOAP header. RequestHeader is the soap header and authToken is a member of that header. See http://code.google.com/apis/adwords/docs/headers.html and http://code.google.com/apis/adwords/docs/#soap for more details.
I also wish to point out that AdWords API official forum is http://groups.google.com/group/adwords-api, where we regularly answer questions on AdWords API. If you have any followup questions, feel free to ask on the official forum.
Cheers,
Anash

Categories