This guide describes how to develop apps and services using Globus Auth, how to register your login provider, how to leverage linked identites to allow your users to use whichever login provider they want, which libraries and resources to use to make your life as a developer easier, and sample apps and services.

1. Developing an Application Using Globus Auth

A Globus Auth App is used to authenticate users and/or to obtain access to other services. At a very high level, the development cycle consists of:

  1. Registering an application client at https://developers.globus.org.

  2. Obtaining authorization. Applications request access to services via scopes using a standard OAuth2 flow.

  3. Using tokens to authenticate to services.

Those are the basics. Apps that want to provide their users with a more complete, integrated experience can then start looking into features such as skinning and other features such as allowing users to initiate linking identities from right inside your app.

Applications can make use of several different services, allowing them to implement features and orchestrate flows that wouldn’t be possible by using any single service.

1.1. Registering an Application

All apps that you register will be part of a project. Two basic kinds of clients that are available for registration:

  • Confidential clients are clients that are capable of keeping client credentials secret. An example of this would be an application that runs on a web server backend. Any client that can be confidential should be confidential for the protection of its users. Confidential clients must authenticate all calls to Auth as described here. This is the type of application you will get if you leave the Will be used by a native application checkbox unchecked.

  • Non-confidential or native applications. Use this client type for CLI apps or other native applications. Native apps must use PKCE. This is the type of client you will get if you check the Will be used by a native application checkbox.

The key difference between the two is whether the client can keep it’s private credentials secret. Any client that is distributed as a binary cannot keep secret credentials; even if attempts are made at obfuscation, extracting the credential will not be difficult for an attacker.

1.2. Obtaining Authorization

Globus Auth is fully spec compliant OAuth2 implementation. It is recommended that developers use an off-the-shelf OAuth2 library. Below is a description of the basic authorization flow. Sections of the OAuth2 specification are referenced for more details.

  1. Authorization request (https://tools.ietf.org/html/rfc6749#section-4.1.1). The application client constructs a link to an authorization page and directs the user to it. The URL is https://auth.globus.org/v2/oauth2/authorize with the following URL encoded query params:

    • client_id. The UUID of the client application.

    • redirect_uri. The URI the user will be redirected back to for the authorization response. Must be pre-registered for this client.

    • scope. A space or comma separated list of scopes the application is requesting access to. If refresh tokens are needed, include the offline_access scope.

    • state. An opaque value that is returned to the client in the authorization response. The client should use this value to prevent cross-site request forgery as described in https://tools.ietf.org/html/rfc6749#section-10.12.

    • response_type. Value must be code.

    • If the application client is a native app the request must also contain a code_challenge and code_challenge_method as described in the PKCE section below.

    • All parameters must be URL encoded.

    • Example of an app requesting access to Globus Transfer and the Globus Auth Identities API with refresh tokens: https://auth.globus.org/v2/oauth2/authorize?client_id=69ba5e62-7285-45db-952d-e0bb73b5eac7&scope=urn%3Aglobus%3Aauth%3Ascope%3Atransfer.api.globus.org%3Aall%20urn%3Aglobus%3Aauth%3Ascope%3Aauth.globus.org%3Aview_identities%20offline_access&response_type=code&redirect_uri=https%3A%2F%2Fwww.example.org%2Fmy_app%2Flogin&state=g6l14b2xlgx4dtce8d2ja714i

  1. The user is prompted to authenticate, and to consent to giving the client application access to the requested scopes if they have not previously consented (if they have already consented this screen is bypassed).

  2. Authorization response (https://tools.ietf.org/html/rfc6749#section-4.1.2). If the user successfully authenticates and consents they will be returned to the redirect_uri included in the authorization request, with the following included as URL encoded query params:

    • code. The authorization code the client application will use to exchange for access/refresh tokens.

    • state. The value the client provided in the authorization request.

  3. Access token request (https://tools.ietf.org/html/rfc6749#section-4.1.3). To exchange the code for an access token, a POST is made to https://auth.globus.org/v2/oauth2/token with the following URL encoded query params:

    • grant_type. Value must be authorization_code.

    • code. The code received in the authorization response.

    • redirect_uri. Must be identical to the value sent in the authorization request.

    • client_id. Once again, the UUID of the client application.

    • If the application client is confidential it must authenticate this call using its client credentials. If the client is a native app it must instead include a code_verifier parameter as described in the PKCE section below.

  1. Access token response (https://tools.ietf.org/html/rfc6749#section-4.1.4). The token response is described in the following section.

1.3. Using Tokens

A successful token response from Globus Auth contains one or more access tokens, and zero or more refresh tokens. The following is an example response from the request above:

{
        "access_token": <access-token-for-globus-transfer>,
        "id_token": <id-token>,
        "expires_in": 172800,
        "resource_server": "transfer.api.globus.org",
        "token_type": "Bearer",
        "state": "g6l14b2xlgx4dtce8d2ja714i",
        "scope": "urn:globus:auth:scope:transfer.api.globus.org:all",
        "refresh_token": <refresh-token-for-globus-transfer>,
        "other_tokens": [
                {
                        "access_token": <access-token-for-globus-auth>,
                        "expires_in": 172800,
                        "resource_server": "auth.globus.org",
                        "token_type": "Bearer",
                        "state": "g6l14b2xlgx4dtce8d2ja714i",
                        "scope": "urn:globus:auth:scope:auth.globus.org:view_identities",
                        "refresh_token": <refresh-token-for-globus-auth>}
        ],
}

Globus Auth, unlike most OAuth2 implementations, supports providing access to multiple different resource servers, and can therefore return multiple access/refresh tokens in the same response. In order to conform to standards (and to allow off-the-shelf libraries to work) the token response for the first requested scope looks like that of any other standards compliant OAuth2 server, and any additional tokens are included in the other_tokens array.

After receiving the response the application client should do the following:

  • Verify that it received the expected scopes.

  • Verify that the state parameter matches what was sent in the authorization request.

  • Store the token(s) for future use, along with their expiry time. Application clients should always inspect the expires_in value (in seconds) of all received tokens; it may differ from one request to the next.

Access tokens are then used to authenticate against services by including them in the Authorization header of HTTP requests, e.g:

Authorization: Bearer <access-token-for-globus-transfer>

When an access token is nearing its expiry time the application needs to retrieve a new one, either by performing another authorization flow as described above (except this time the user won’t be prompted for consent again), or by performing a refresh token grant.

Refresh tokens are long lived credentials and should never be sent over the wire except when doing a refresh token grant against Globus Auth. Please store them securely.

1.3.1. Token Invalidation

For the security of their users application clients should invalidate tokens when they are done with them, for example as part of a logout operation. This is particularly important for long-lived refresh tokens.

1.4. Client Authentication

Clients authenticate to Globus Auth with a HTTP basic auth header, using client credentials created in the registration interface:

Authorization: Basic <credential>,

where <credential> is the base64 encoded client ID and client credential, separated by a single colon. For instance, in Python the header could be constructed as:

client_id = "69ba5e62-7285-45db-952d-e0bb73b5eac7"
client_credential = "QWxhZGRpbjpPcGVuU2VzYW1l"
client_auth_header = "Authorization: Basic {0}".format(
        base64.b64encode("{0}:{1}".format(client_id, client_credential)))

1.5. PKCE

PKCE (RFC 7636) is a security protocol that allows unauthenticated ("native") application clients to use the three-legged OAuth2 authorization code grant. Confidential clients may use it as well; doing so may guard against certain attacks that would be made possible if client credentials are compromised.

Before starting the authorization flow the application client must generate a code_verifier which meets the following requirements:

  • Generated using a reliably random (i.e, unguessable) method.

  • 43-128 characters long consisting of letters, numbers and the characters -._~.

  • Must be freshly generated for each request.

Second, a code_challenge is created by taking URL safe base64 encoding of a SHA256 digest of the code_verifier.

The authorization URL is then created as described above, but with the two following additional parameters:

  • code_challenge, as just described.

  • code_challenge_method, whose value MUST be SHA256.

Just as with the normal flow, the user is then prompted to authenticate and consent, and is sent back to the redirect_uri. For the final step, the access token request, the application client must include the code_verifier parameter created above.

These additions allows Globus Auth to verify that the request originated from a particular instance of the application client, so that an attacker is unable to steal a token even if they manage to compromise the authorization code.

1.6. Skinning

Globus Auth supports skinning, so that when a user comes in from your app the look of Globus Auth matches that of your application. Setting this up is a manual process, please contact us for more details!

2. Developing a Service

A Globus Auth service is a system that provides access to resources owned by users, and wants to provides access to those resources to applications used by end-users, typically via a HTTP API. Services can also expand their functionality by in turn making use of other services.

Registering a Service is currently a manual process. Please contact us for more information!

3. Adding an Identity Provider

Please contact us if you wish to add your identity provider to Globus Auth to allow your users to use their normal login for authenticating against apps and services.

4. Managing Projects

All apps and services that you register will be part of a project. You can add and remove admins to allow others to manage the project. All admins are co-equal, meaning that anyone you add will be able to add/remove/edit all of your apps and services.

When registering you are asked to provide a contact email. It will only be used to give you important notifications related to your project. If you expect your project to last many years, please make sure to keep the contact email current.

5. Libraries and Resources

5.1. Using the Globus Python SDK

Globus provides a Python SDK for interacting with its APIs, including Globus Auth and Transfer. Documentation can be found here.

5.3. Sample Applications and Services Using Globus Auth

The Globus Sample Data Portal contains an example of both an application and a service. Beyond basic app/service functionality, it demonstrates the use of dependent services (in this case Globus Transfer), client identities and other features.


© 2010- The University of Chicago Legal