1

A bit of background

I'm working on an Installed Application project that handles possibly very many Google APIs and their scopes for each user. One major issue I'm having is when a user selects a large number of scopes to authenticate, they are supplied in the URL as parameters and cut off. For example, the url might terminate as such (line breaks for readability):

...%20https://www.googleapis.com/auth/admin.directory.userschema.
readonly%20https://www.googleapis.com/auth/admin.reports.audit.readon
ly%20https://www.googleapis.com/auth/admin.rep

This is a result of wanting my users to only have to authenticate once, but I realized that it wouldn't be too terrible to have to do it once per API they're using. So I broke it up, but then found that after authenticating again it would overwrite their access. So, I looked in to the Incremental Authorization mentioned on the docs, only to find out that no it won't work for Installed Apps and there is apparently no intention for it to do so:

I think the problem here is that you are using the installed application OAuth2 flow, which contrary to the documentation doesn't support the include_granted_scopes parameter.

Ok, so at this point it sounds like I have two options. The first and obvious option is to maintain a separate token for each API. However, before I commit myself to that route I looked in to how the Python-based Google Apps Manager handles it since upon authenticating I don't see any of the scopes in the URL, so I assume it's being sent as a POST body.

Main Question

Using the Google API Client Library for .NET for an Installed App, is it possible to authenticate without supplying the scopes as URL parameters? I've tried using PowerShell and Invoke-RestMethod to try and get something like a POST request working, but have not had any luck.

Community
  • 1
  • 1
squid808
  • 1,430
  • 2
  • 14
  • 31

2 Answers2

0

I don't think this is a problem with the Client library. The problem is that the initial request for authorization. The one that pops up the list to the users is a HTTP get.

https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code

As far as I know the max length of http get is 2000 characters. If its more then that its going to get cut off by some browsers.

Option:

I read about incremental authorization.

Google supports incremental authorization, which enables your app to request initial permissions at sign-in and later can request additional permissions, typically just before they are needed. For example, if your app allows users to save music playlists to Google Drive, you can ask for basic user information at sign-in, and later ask just for Google Drive permissions when the user is ready to save their first playlist. At this point, the consent dialog box asks the user only for the new permissions, which gives them a simpler, in-context decision to make.

I can only find information about web, Android, or iOS. This does not mean that its only supported by them. All those are Googles SDKs so it could be something that they only allow internally. However this may be something that we can add to the client library. I suggest you add an issue request. Google-api-dotnet-client issues

It looks like it should be possible. there is a http/rest example here

I think the only other option is going to be what you are doing now and having a refresh token for each of the APIs or each section of your application.

Update

After some digging include_granted_scopes isn't in the client library. Which means this would have to be added or you would have to do it the hard way without the client library. Issue request is probably the way to go.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • I covered why the client library won't handle Incremental Authorization in the question explicitly, and also why it doesn't matter. I'm currently working on a pull request to add it in, even though it won't work for an Installed App like mine. See the links I referenced in the question for more background - they have specifically said it won't work for installed apps, by design. – squid808 Nov 04 '15 at 14:48
  • it should still work for an installed app. Have you tried doing it with an installed app? doing the raw http requests. Just because the documentation says it doesn't work doesn't mean that it is correct. – Linda Lawton - DaImTo Nov 04 '15 at 14:58
  • I've done it with raw requests - it properly puts the ```include_granted_scopes=true``` in the url, but it doesn't append the scopes, it just replaces. So if I auth scope A, I can request A but not B. If I then re-auth using that parameter as true with scope B, I can request B but not A. I would expect that it would be B _and_ A. Also, the documentation says that it DOES work. [This library issue](https://goo.gl/nTLI6e) is where they say the docs are wrong, and it won't work with installed apps. See [this SO question](http://goo.gl/ogm0UY) for a better explicit showing of PoC on the issue. – squid808 Nov 04 '15 at 15:07
0

I've determined that this is not possible. After crawling the python code that I assumed was working differently, I used Fiddler to capture the initial URL being sent to the browser and saw that indeed it is doing the exact same with query parameters. It appears that the scopes are just being lost in the redirects for some reason that I'm not able to catch using the browser developer tools directly.

That said, I no longer have a basis for comparison or any reason to think that other projects work in a way other than what is documented, so I think my question is null and void.

Edit: And at the time of writing, despite documentation, incremental auth is not supported for installed apps.

squid808
  • 1,430
  • 2
  • 14
  • 31