in https://developers.google.com/calendar/api/v3/reference/calendarList/list?apix=true#auth
I can see, that I can use OAuth2 and API-Key to authenticate for the calendarList endpoints
My first test with postman and OAuth2 works perfect: I get the JSON List of all calendars of the autheticated user
Now I test the entpoint with authentication over API-Key
I create the API-Key and enabled the calendar for this api key:
Problem:
I've tested it with postman and Auth-Type=ApiKey and with Parameter key=MYAPIKEY but always get error 401 "Request is missing required authentication credential"
Does anyone have a (postman) example to access the google calendard api with an API-Key?
API keys are only used to access public data not private user data.
In order to use an api key with postman you would simply take the rquest and add key=YourKEY on the end
The following is a good example of this but unfortunately there is currently an issue with API keys and public calendars. Requiring authorization instead of just an api key194427607
https://www.googleapis.com/calendar/v3/calendars/en.danish%23holiday%40group.v.calendar.google.com?key=[YOUR_API_KEY]
You are not going to be able to use calendar list without being authorized calendarlist.list states in the documentation that you must be authorized as its private user data.
Related
I want to get my own Google Contacts so I read up on the People API documentation, on the "Authorize Request" section under the "Acquiring and using an API key" it says:
API keys: A request that does not provide an OAuth 2.0 token must send
an API key. The key identifies your project and provides API access,
quota, and reports.
The API supports several types of restrictions on API keys. If the API
key that you need doesn't already exist, then create an API key in the
Console by clicking Create credentials > API key. You can restrict the
key before using it in production by clicking Restrict key and
selecting one of the Restrictions.
So that seems easy enough, I went to the project page and created an unrestricted API Key, then I can create this request URL: https://people.googleapis.com/v1/people/me?key=API_KEY&personFields=names, with the API key just in the URL, as this statement suggest.
After you have an API key, your application can append the query parameter key=yourAPIKey to all request URLs.
But when I run the URL I posted before it returns this:
{
"error": {
"code": 401,
"message": "The request does not have valid authentication credentials.",
"status": "UNAUTHENTICATED"
}
}
What am I doing wrong? :(
Turns out the solution is pretty simple and I feel quite stupid, it isn't possible to access your own Google Contacts or any other private data using the API key, if you're trying to access any private data you should use OAuth 2.0 and not an API key (unlike for instance a public YouTube play-list where you CAN use an API key). Thanks to #Mateo Randwolf
I'm providing an external-facing REST GET API service in a kubernetes pod on AWS EKS. I had configured an ALB Ingress for this service which enforces Cognito user pool authentication. Cognito is configured with Authorization code grant with the openid OAuth scope enabled.
If I invoke my REST API from the browser, I get redirected to the Cognito login page. After a sucessful authentication on the form here, I can access my REST GET API just fine. This works, but this is not what I'd like to achieve.
Instead of this, I would need to use a Bearer token, after getting successfully authenticated. So first I invoke https://cognito-idp.ap-southeast-1.amazonaws.com using Postman with the request:
"AuthParameters" : {
"USERNAME" : "<email>",
"PASSWORD" : "<mypass>",
"SECRET_HASH" : "<correctly calculated hash>"
},
"AuthFlow" : "USER_PASSWORD_AUTH",
"ClientId" : "<cognito user pool id>"
}
and I get a successful response like:
"AuthenticationResult": {
"AccessToken": "...",
"ExpiresIn": 3600,
"IdToken": "...",
"RefreshToken": "...",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
In the last step I'm trying to invoke my REST API service passing the Authorization HTTP header with the value Bearer <AccessToken> but I still get a HTML response with the login page.
How can I configure Cognito to accept my Bearer token for this call as an authenticated identity?
Quoting AWS support on this topic: "the Bearer token can not be used instead of the session cookie because in a flow involving bearer token would lead to generating the session cookie".
So unfortunately this usecase is not possible to implemented as of today.
STANDARD BEHAVIOUR
I would aim for a standard solution, which works like this:
API returns data when it receives a valid access token, or a 401 if the token is missing, invalid or expired - the API never redirects the caller
UIs do their own redirects to the Authorization Server when there is no token yet or when a 401 is received from the API
If it helps, my OAuth Message Workflow blog post demonstrates the 3 legged behaviour between UI, API and Authorization Server.
API GATEWAY PATTERN
It is perfectly fine to use an API Gateway Design Pattern, where token validation is done via middleware before hitting your API.
However that middleware must return a 401 when tokens are rejected rather than redirecting the API client.
IMPACT OF APIs REDIRECTING THE CLIENT
This may just about work for web UIs, though user experience will be limited since the UI will have no opportunity to save the user's data or location before redirecting.
For mobile / desktop apps it is more problematic, since the UI must redirect using the system browser rather than a normal UI view - see the screenshots on my Quick Start Page.
CHOICES
Any of these solutions would be fine:
Possibly the middleware you are using can be configured differently to behave like a proper API Gateway?
Or perhaps you could look for alternative middleware that does token validation, such as an AWS Lambda custom authorizer?
Or do the OAuth work in the API's code, as in this Sample API of mine
MY PREFERENCE
Sometimes I prefer to write code to do the OAuth work, since it can provide better extensibility when dealing with custom claims. My API Authorization blog post has some further info on this.
I have the following setup on the same machine:
WSO2-AM
WSO2-IM-KM (Identity manager as key manager)
The identity manager federates authentication to an external OpenID identity provider.
What I've done so far:
Share the databases between the two components
Make WSO2-AM delegate the authentication to WSO2-IM-KM
Configure the external provider to the generated service provider (generated in WSO2-IM-KM when creating an application in WSO2-AM store)
The current behavior:
I can obtain an authorization code by calling the following URL : https://my.site:9444/oauth2/authorize?response_type=code&client_id=pkYcC4xFQ1jt6dQbdZAe6savv4oa&scope=phone+email+address+openid+profile&redirect_uri=https://my.site:9443/store/jagg/jaggery_oidc_acs.jag&nonce=3734e7d4c22f1&state=128d20e14c884, the authentication succeeds, then the jaggery_oidc_acs.jag endpoint fails
Since the jaggery_oidc_acs.jag endpoint fails, I manually retrieve the code then POST it to https://my.site:8243/token which returns me an access_token, a refresh_token, and an id_token
My problems :
How am I supposed to automate the manual step I described before? Am I in charge of creating a dedicated endpoint to do it, in order to keep the authorization_code obfuscated from the client, or is there a built-in endpoint in WSO2? If appropriate, what is this endpoint?
Is there an endpoint that generates the oauth2/authorize URL?
After further research:
I have found the following document https://docs.wso2.com/display/IS540/Authorization+Code+Grant that seems to indicate that I need a "client", but I don't have one, I just need my API to be authenticated with the external identity provider.
Answering to problem 01
If you want to use authorization code grant type to get access token definitely there should be a callback URL to get authorization code. If your callback URL is real no need to do any manual step, simply just retrieve authorization code from request query parameters sent to callback URL. You can check this behavior from playground2 sample application [1] where callback URL is http://localhost:8080/playground2/oauth2client.
Answering to problem 02
Please check OAuth2AuthzEPUrl tag in identity.xml
[1] https://docs.wso2.com/display/IS570/Setting+Up+the+Sample+Webapp
I would like to send an email on behalf of a user using Postman (Office 365). I have the email id and password of that account. After doing some research, I have found that I need to login, using a browser, to get the authorization code and then I can perform the next steps from Postman (getting the access token and using the Microsoft Graph Explorer) to send the email.
I would like to get the authorization code using Postman (not browser). I tried and got the following error (which is what should come the way I have requested the API)-
In short, I want to send email from Graph API using a REST client like Postman (right from authorization to sending email). Is this possible?
(I have already read these documents but did not help me get there-
https://developer.microsoft.com/en-us/graph/docs/concepts/rest
Accessing Microsoft Graph API without using login page
Automatically Log-In To Office 365
)
Yes, it is very possible, in fact, you can use all of the Microsoft Graph API from Postman or any other program which can make HTTP requests.
All you need to do is to get access token to use in your requests to the Graph API, and there at least 4 ways which allow you to do so without user interaction. But the process requires some preparation since you need to create an OAuth App in order to be able to use the Graph API.
Since I had to do the same myself and it wasn't easy to collect all the bits of information necessary, I've written a full guide on this subject including Postman examples:
Getting Access Token for Microsoft Graph Using OAuth REST API
In large you need to do the following steps:
Register OAuth App
Configuring App Permission
Use one of the following flows, depending on the information you have:
Flow 1: Get Access Token from Client Credentials (Client credentials Grant)
Flow 2 – Get Access Token From Client & User Credentials (Resource Owner Credentials Grant)
Flow 3 – Get Access Token From Refresh Token (Refresh Token Grant)
Flow 4 – Get Access Token From Another Access Token (On-Behalf-Of Grant)
Use the access token in requests to Microsoft Graph API
All of those steps are explained in the article.
Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).