-
Notifications
You must be signed in to change notification settings - Fork 89
Demo Wing OAuth server
If you are comfortable using Google Cloud, or are already hosting other parts of your infrastructure on Google Cloud, then you can simply create a service account yourself and give Wing its email address. This lets you stay in complete control of your service account, and create and revoke your own keys.
- Create a service account in one of your cloud projects.
- Tell Wing the email address of the service account you
just created. It looks something like
[ACCOUNT]@[PROJECT].iam.gserviceaccount.com
. - Create a key for the service account. You need to store this key securely and must not share it with anyone else - even Wing.
If you do not want to use Google Cloud, just tell Wing your preferred base domain (e.g., wing.com) which will serve as your USS name. Wing will provide a key as a JSON file that must be kept secret.
Use your service account key JSON file to get an OAuth access token with the
email
scope. See the
Google OAuth documentation
for details. There are Python and Java client libraries available, but the
documentation also describes how to do this manually with HTTP requests.
In Python:
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(
'service-account.json').with_scopes(['email'])
Make a POST request to https://utm-oauth-demo-us.appspot.com/oauth/token
. You
must specify the following URL query parameters:
-
grant_type
must always beclient_credentials
. -
scope
is a space-separated list of OAuth scopes you want to request. Valid values includedss.read.identification_service_areas
anddss.write.identification_service_areas
. -
intended_audience
is the hostname of the service (DSS or USS server) you actually want to call. The JWT that is issued will be restricted to use only that server, ensuring that the server can't take your JWT and use it to impersonate you to other parties.
You must also send an Authorization
header containing the access bearer token
generated in Step 1.
A successful response looks like this:
{
"access_token": "...",
"expires_in": 1800,
"scope": "dss.read.identification_service_areas",
"token_type": "Bearer"
}
You can use the access token to make requests to the DSS or USS server.
-
{"error": "invalid_grant"}
- ensure you set thegrant_type=client_credentials
query parameter. -
{"error": "invalid_client"}
- ensure that:- you have added an Authorization header with a Bearer token
- the Bearer token has the
email
scope - you have included an
intended_audience
query parameter - the service account you're using is allowed to use the service
-
{"error": "invalid_scope"}
- you requested a scope that you have not been given permission to use.
The script below will retrieve an access token when provided with a service account JSON key file.
# python3
"""Small example showing how to fetch a JWT."""
import argparse
import json
import sys
import urllib.parse
# pip install requests google-auth
from google.auth.transport import requests
from google.oauth2 import service_account
OAUTH_TOKEN_URL = 'https://utm-oauth-demo-us.appspot.com/oauth/token'
def ParseArgs(args):
"""Parse passed command-line arguments."""
parser = argparse.ArgumentParser(
description='Small example showing how to fetch a JWT')
parser.add_argument(
'--service-account-json',
help='path to a JSON service account file',
required=True)
parser.add_argument(
'--audience',
help='the "aud" that the JWT should be issued for',
required=True)
parser.add_argument(
'--scope',
nargs='+',
help='OAuth scope to request (e.g. '
'"dss.write.identification_service_areas"). Can be specified multiple '
'times',
required=True)
return parser.parse_args(args)
def Main(argv):
"""Small example showing how to fetch a JWT."""
args = ParseArgs(argv)
# Read the service account credentials from the file and create an authorized
# session object that knows how to set the Authorization HTTP header.
credentials = service_account.Credentials.from_service_account_file(
args.service_account_json).with_scopes(['email'])
session = requests.AuthorizedSession(credentials)
# Request the JWT.
url = '{}?grant_type=client_credentials&scope={}&intended_audience={}'.format(
OAUTH_TOKEN_URL, urllib.parse.quote(' '.join(args.scope)),
urllib.parse.quote(args.audience))
response = session.post(url)
print(json.dumps(response.json(), indent=2))
if __name__ == '__main__':
sys.exit(Main(sys.argv[1:]))
A token generated by this auth server may be validated by checking the signature against this public key:
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlImo4cK6pDDpPDJp3ETO
AghFLL35W+fNx3drwbq78+eAKrAkNuBN05JKDF5i8+EcnVzKSMZCrebx9mlBnctU
bEpnVefJcj2pmLyOJVbn7wfPdebkGFFiFPKzyzF71hZjX1LNuTSNklvsX+Ns7R78
h0wfw0ICG3NcSrk/f+IxqnH1iPn/d6E7OeHz3nNPxZV5OeEnP61Myy11f5/oXq7v
GHJhqfgG225Ld7cfwTdyMMBkfEcI4ha2lgyDcrgTqofW7+hzVXdXWI5Bkj8awEAk
jmIh08UtXHYygGAfJ+6TirbI/PodrL7IXwAMNiPyPMBdJHh7hnaDr9c3Z10kcEhZ
leqjyXrohiHtIitBsDLJfHSE3ta5QYGvyLqqtVAo//BAWpdGSscEg5RkLT514siP
jJKUsiwi8s073S8ayplHFaUBd8GnvG1nTvztjsVl2pkdQ9FYlkU3yat5cof25zXm
bVD6elaG9mh4Flp+DvxMvTGBCuO+M0UMqOuVRPJt9G0T2269M72hcO+SqVIk5Ko3
39HEOPihnALRE/GbvtdKV++qjE00ePeB8fXJOl+qePlHTxQBdBGq8fu+n/2JOgz+
slTZwk1QYA0iw5I8QI/SFLSFgtxYgiopQ/8C+1aN3yRhB/HpJThAXYu684HT3uVv
6Htni4wEiCUNVhNF/gb1+BUCAwEAAQ==
-----END PUBLIC KEY-----