Remoto - VFS: Google Oauth2
Remoto - VFS
Google Oauth2

Description

A VFS authentication node providing a VFS_auth subclass that will authenticate a one-time access code from a Google OAuth2 endpoint.

This assumes that a user has already logged in using google credentials, which should happen from a login screen before the session, as found in mportal. The auth code (which is renamed as an authtokenonce cookie) is passed along to the VFS_remotoserver authentication mechanism during login.

If VFS_session tokens are used, this authentication will happen a first time, and a user will be considered to have a valid session until their VFS token expires or is removed, which is to say that the Google credentials are only used on initial login, and then normal VFS mechanisms are used after that.

If VFS_session tokens are not used, this will authenticate upon each page reload, and a new authcode will be generated and resolved.

In neither case can a user's access be directly/immediately revoked during a session without using VFS methods like those found in the VFS admin. Once authenticated the session is separate from Oauth2 and no link is kept.

Setup

A lot of information can be found here: https://developers.google.com/identity/protocols/oauth2/web-server

The API is very confusing depending on use case, coding language, and authentication pathway.

For this implementation:

  1. Create a project at https://console.developers.google.com
  2. Go to https://console.developers.google.com/apis/credentials with the project selected and create an "OAuth 2.0 Client IDs" entry named something like "VFS Portal" or "VFS Auth". This will be the credential set for this authentication node.
  3. For "Authorized JavaScript origins" enter whatever URIs are needed for production or development, knowing that they don't necessarily need to resolve externally and are used in http referrer headers. During authentication, the http referrer must be an https address that matches a known one entered here.
  4. For "Authorized redirect URIs" enter something. In this implementation no redirect actually ever happens to this URI, but an entry here must match what is provided in the node definition. It should start with "https".
  5. You will need the Client ID and Client secret from this creation page for the node definition.
  6. Click create, and note that the URIs indicated will be added to the OAuth consent screen.
  7. Go to the OAuth consent screen tab at the left, and choose "internal" or "external" for account access. This credential creation must happen from within an organization, so if you want to restrict access to only domain members, use "internal".
Note
This implementation will not work for a Unity client, because we don't have an easy mechanism to produce our one-time access code.

Installation

There are no external libraries and requests are entirely REST based. A normal installation of Qt with QNetworkManager will support all requests.

Mutiple google_oauth2 nodes can be included in a single VFS config.

Usage

Instead of using Google's client_secrets.json, we include the components separately in the node definition:

<google_oauth2 name='oauth2'
client_id="348288129992-e2gnmlbeas8q8okfnmsv8entb0v0lttk.apps.googleusercontent.com"
client_secret="7hhDvqcuNoY9c-J5lDXyFyEh"
redirect_uri="https://neon.themolecule.com"
thread='1' debug='0' />

The debug flag will produce very verbose information about each authentication step.

This node can be mixed with other authentication methods in the normal VFS_auth way, however it does not recognize username/password. In a mixed environment, for instance, it may be desirable to have a back door user authenticated by VFS_passwd. If a front end is attempting to use VFS_google_oauth2, it will want to force a user into a loop until they are authenticated, so url query parameters may be needed for a backdoor user.

Flow

In this implementation the username/password or whatever auth information for a user are never sent to the VFS server. Instead, Google's libraries are used before VFS authentication to produce an access code, which will be passed by vfs_client_javascript as a VFS_AUTHTOKENONCE cookie. This is implemented in the mportal library.

The access code will only be valid for one use, and the cookie will be removed immediately.

The server receives this access code as part of the credential package, and using the client_id and client_secret, will request a JWT (JSON Web Token) which contains encrypted data about the user's session.

At this point in the process, we have not used any special Google APIs other than basic profile email and openid.

For group membership, which is an important aspect of VFS ACL control, we require stuff from here: https://developers.google.com/admin-sdk/directory/v1/reference/groups/list

This hasn't been completed yet. Access to services beyond profile email and openid seem to require site validation from Google.