How to specify OAuth audience (audience:server:client_id returns invalid_scope) - windows

We're writing Windows app and we also have backend server. And we want to implement Google Login. So the Windows app asks the user, it receives the JWT token and passes it to our server. I the token, there are 2 keys: aud and azp. On our other platoforms (iOS, Android), the azp is the OAuth Client ID of the application from Google Cloud Console and aud is OAuth Client ID for our server. But on Windows, they are both same. On other platform, this is handled by libraries provided by Google, but on Windows, we're using low-level HTTP. But we can't find a way to specify the aud. How can we do it?
EDIT: I found out about audience:server:client_id:... in scope, but it doesn't work for me either. It gives me Error: invalid_scope.
This is the request (using HTTPie):
http -v https://accounts.google.com/o/oauth2/auth client_id==windows-ios-app-client_id.apps.googleusercontent.com redirect_uri==my.bundle.id: response_type==code 'scope==audience:server:client_id:server-client-id.apps.googleusercontent.com'
GET /o/oauth2/auth?client_id=windows-ios-app-client_id.apps.googleusercontent.com&redirect_uri=my.bundle.id%3A&response_type=code&scope=audience%3Aserver%3Aclient_id%3Aserver-client-id.apps.googleusercontent.com HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: accounts.google.com
User-Agent: HTTPie/0.9.2

I think we should provide this scope while you request for token. This is probably automatically done if we use Google/Sign-In library, provided that we set the server client id.
[GIDSignIn sharedInstance].serverClientID = #"YOUR_SERVER_CLIENT_ID_HERE"
By the way, If any am looking for a way to implement the same using AppAuth. I did not find any solution yet.
Send the web client id as a parameter audience=WEB_CLIENT_ID when requesting token endpoint.

Related

Google Drive API with files.get migrating to HTTP "webViewLink" - how to bypass 100mb virus page?

Google released this blog post which says:
If you authorize download requests to the Drive API using the access
token in a query parameter, you will need to migrate your requests to
authenticate using an HTTP header instead. Starting January 1, 2020,
download calls to files.get, revisions.get and files.export endpoints
which authenticate using the access token in the query parameter will
no longer be supported, which means you’ll need to update your
authentication method.
and then says:
For file downloads, redirect to the webContentLink which will instruct
the browser to download the content. If the application wants to
display the file to the user, they can simply redirect to the
alternateLink in v2 or webViewLink in v3.
however if we use webContentLink then we will hit the 100mb virus page mentioned here.
I can see that the migration has been delayed, however sooner or later this will happen, and we want to future-proof the application.
How will we be able to download content without hitting the 100mb virus limit, after this change is implemented?
If you authorize download requests to the Drive API using the access token in a query parameter, you will need to migrate your requests to authenticate using an HTTP header instead.
Example query param:
GET https://www.googleapis.com/drive/v3/files/[FILEID]?access_token=[YOUR_ACCESS_TOKEN] HTTP/1.1
Accept: application/json
Example requests header:
GET https://www.googleapis.com/drive/v3/files/[FILEID] HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
Assuming that you can do the http header option then you should not have any issues with the download as mentioned. The issues with download only come into play if you cant add the authorization header. In which case i think you would need to go with option number two and export the files directly.

How to get an access token from Google without an api library?

I am working on an Elixir Phoenix web project where I want to interact with Google's Indexing API.
Google uses OAuth2 to authenticate api requests and actually has a decent documentation on this.
But it only explains the process using one of the supported libraries in Python, Java, PHP or JS.
I would like to make the HTTP requests by myself to retrieve that access token. But the request format (including headers or parameters) is nowhere documented and I cannot even figure out from the libraries' source code.
I have tried requesting https://accounts.google.com/o/oauth2/token (also other eligible URLs) in Postman with the "OAuth 2.0" request type.
But it was all just guessing and trying. All the research did not help.
There are useful instructions including HTTP/Rest examples at Using OAuth 2.0 for Web Server Applications. Each step has the individual parameters fully documented. Here are some useful excerpts.
Send user to Google's OAuth 2.0 server. Example URL:
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&
response_type=code&
client_id=client_id
Retreive authorization code (your domain). Example:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Request access token. Example:
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://oauth2.example.com/code&
grant_type=authorization_code
Use API. Example:
GET /drive/v2/files HTTP/1.1
Authorization: Bearer <access_token>
Host: www.googleapis.com/

Firefox SPNEGO Negotiate protocol - multiple connections?

I'm using gssapi/Kerberos authentication in my web application, and I want single sign on via the browser.
The problem is, Firefox sends an initial request to the server with no authentication, and receives a 401. But it includes a keep-alive header:
Connection: keep-alive
If the server respects this keep-alive request, and returns a WWW-Authenticate header, then Firefox behaves correctly and sends the local user's Kerberos credentials, and all is well.
But, if the server doesn't keep the connection alive, Firefox will not send another request with the credentials, even though the response has the WWW-Authenticate header.
This is a problem because I'm using Django, and Django doesn't support the keep-alive protocol.
Is there a way to make Firefox negotiate without the keep-alive? In the RFC that defines the Negotiate extension, there's nothing about requiring that the same connection be re-used.
Alternatively, is there a way to make Firefofx preemptively send the credentials on the first request? This is explicitly allowed in the RFC.
That header is HTTP 1.0, wake up, fast-forward 15 years and your problems will go away. Firefox works very well with SPNEGO.

How to develop test-automation using Postman when OAuth 2.0 authorization is required

I have an ASP.NET Web API 2 which is using OAuth 2.0 for authorization. And let's imagine I have a simple Web API method, like:
GET: http://host/api/profiles/user123 (requires OAuth 2.0 token)
So, with Postman, it is easy to test this Web API. I get an OAuth token for user123 from the Web API OAuthAuthorization method and then I use that token in the header of the HTTP request:
GET /api/profiles/user123 HTTP/1.1
Host: {host}
Authorization: Bearer {Token}
Content-Type: application/json
Cache-Control: no-cache
However, if I save my test and run it later (either by Postman itself or by Newman), the token will be expired at that time and it won't work.
How can I make Newman to get a new token automatically for user123 and use it in the HTTP request?
Note: I know how to use Postman's Authentication helpers to ask for a new token. But this scenario doesn't fit the test-automation. In test-automation, I want to remove any human interaction.
It's simple, get your access token at run time and save it into environment variable. Then use it in your next Get request.
In Get Token request, do this in Tests sections:
var body = JSON.parse(responseBody);
pm.environment.set('AccessToken', body.access_token);
In your main Get request, you can use the environment variable in Authorization header:
Authorization: Bearer {{AccessToken}}
Hope this helps.

Token based authentication for user and separate module

I have 2 scenarios where I want to implement the token based authentication:
I want to implement token based authentication when a user logs in. i.e.. based on username and password , user should get a token and that token should be used with every request.
I have a separate independent module which has ID and secret Key. It has to communicate with server in specific interval. I want to implement token based authentication for this module also.
In both the cases token should have these properties:
It should be in payload.
It should have a timeout period
When token expires server should provide a new token,if the session is not expired else it should logout.
Is OAuth 2.0 right choice? If any other approach is better, Please tell me.
What should I do to solve this problem?
Which is the best place to put token in request -Payload or header? and Why?
OAuth 2.0 is a good choice for the requirements you mentioned: timeout period and refresh-ability.
Stormpath has an excellent OAuth2.0 implementation that gives you what you are looking for out of the box.
Stormpath has both remote and local OAuth2 Implementations and both are freely available. For the remote case you can rely on our backend using any REST client (http://docs.stormpath.com/guides/token-management/) and any of our SDKs. For the local case you can use our Servlet plugin to run a Web-app with out of the box OAuth2 support. Using the docs link above, you can find documentation for these resources.
Using the Stormpath Spring Boot integration, for instance, you could do something like this:
http -v --form POST http://localhost:8080/oauth/token \
> 'Origin:http://localhost:8080' \
> grant_type=password username=micah+demo.jsmith#stormpath.com password=<actual password>
(This example uses httpie to interact with a locally running Spring Boot instance). The line I've bolded above conforms to the OAuth2.0 spec for authenticating with usernames and passwords. What you get back is a response like:
HTTP/1.1 200 OK
Cache-Control: no-store
Content-Length: 325
Content-Type: application/json;charset=UTF-8
Date: Tue, 04 Aug 2015 16:02:08 GMT
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: account=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4; Expires=Wed, 05-Aug-2015 16:02:08 GMT; Path=/; HttpOnly
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4",
"expires_in": 259200,
"token_type": "Bearer"
}
This provides a bearer token that can be used on subsequent requests as well as an expiration. Plus, it has the advantage of being a JWT - JSON Web Token. The JWT is cryptographically signed to ensure that it hasn't been tampered with and it can be decoded to provide additional meta-information to your client, including user information, access controls and expiration.
You could do something very similar using the grant_type=authorization_code for interacting using an id and secret, such as for the independent module you mentioned.
This article goes into more detail on token authentication with Java.
Full disclosure: I am a Stormpath employee and I wrote the article referenced above.

Resources