OAuth2 is an internet standard that secures endpoints using tokens, consumer authorization, and client secrets. The web API uses OLTU on top of OAuth2 to provide authentication.

Note: OAuth2 must authenticate over HTTPS. The token can be intercepted between the client and the server if HTTPS is not used.

OAuth2 Configuration

The basic steps are:

  1. Establish Client ID and Secret. The Secret is known only to the two parties involved. This is done once only
  2. The client obtains an authorization token using the Client ID and Secret.
  3. Use this token - it is time-limited - to get an access token and a refresh token.
  4. When the access token expires, use the refresh token to get a new one.

Using OAuth2 with API V1

The basic steps are:

  1. User logs in, which is handled in ProcessLoginHandler.
  2. Username and password are validated.
  3. An OAuth access token is created.
  4. This token is stored in the server session.
  5. The token is returned to the client in the GVars object with key "access_token" (BasicWindow).

    Note: The token is not passed in a header or cookie.
  6. app/ngm.js injects the access token into the request header as a Bearer token, using an httpProvider interceptor.
  7. If the access_token is set, map/components/map.js:
    1. Creates a token and registers it on the esriId.
    2. Adds it to the URL (along with the Session ID)
    3. Sets the user ID to AgileAssets.
  8. OAuthSigninHandler.js ? - ESRI code
  9. In MWM models/login.js, the access token is requested from token/request if there is an OAuth token - models/oAuth.js.

Using OAuth2 with API V2 case

The basic steps are:

  1. User logs in - handled in ProcessLoginHandler.
  2. Username and password are validated.
  3. An OAuth access token is created.
  4. This token is stored in the server session.
  5. The token is returned to the client in the GVars object with key "access_token" (BasicWindow).

Setup of OAuth2 tokens - API

The procedure to create access tokens for raw API usage is:

  1. Establish client_id and client_secret
    1. use URI /rest/oauth2/secret
    2. x-www-form-urlencoded
    3. pass form parameters
      1. redirect_uri - the redirect URI - must be valid
      2. client_id - a client id 
      3. grant_type - one of more (comma separated) of - NOTE client_credentials is NOT supported:
        1. authorization_code
        2. password
        3. refresh_token
    4. header values
      1. Authorization - Base64 encoded (see below) <userid>:<password> for a user that is specified as is_admin = true
    5. You get back a JSON object with the client_secret in it 
  2. Read step 4 before starting step 3 - the token from step 3 is time sensitive - 12 hours at present, but it should be a few minutes - say 5.
  3. Get authorization code
    1. Issue HTTP GET request to rest/oauth2/auth
    2. Provide the following parameters:
      1. response_type - value = "code"
      2. redirect_uri - as above
      3. client_id - as above
      4. client_secret - from above
  4. This will cause a redirect to the redirect_uri with the authorization_code passed as a parameter (code)
  5. This URI should then respond:
    1. Validate the request - check server etc
    2. Issue HTTP POST to /rest/oauth2/token
    3. redirect_uri - as above
    4. client_id - as above
    5. client_secret - as above
    6. OR use the Authorization header as "Basic "  followed by the Base64 encoded <client_id>:<client_secret>
    7. grant_type there are 3 types of grant - each with different requirements
      1. authorization_code - requires the authorization code from above, and the user_id
      2. password - requires a username and password - note password CANNOT be null
      3. refresh_token - requires the refresh token from an earlier request
    8. For authorization_code the user to use, in the AA_USER_ID parameter, or using the username parameter (refresh_token uses the previously setup user id)
  6. This returns a response - JSON with:
    1. access_token: the access token to use
    2. refresh_token
    3. token_type: always Bearer - case is important
    4. expires_in: when the access token expires
  7. Use the access token in subsequent requests to the API V2.

Alternative OAuth2 flow

First set up a client id and secret (see above)


OAuth2 also supports the password method of obtaining an access token. The basic steps for this are:

  1. Send HTTP Post request to the /token end point with parameters:
    • grant_type = "password"
    • client_id
    • client_secret
    • username
    • password - cannot be null
  2. Assuming those parameters are valid, you will get a response similar to the one shown below.
  3. Return the access_token in the header of requests, along with AA_USER_ID
  4. Use the refresh_token if the access_token expires to get a new access token. See Using the Refresh Token.


Password Response

{
"access_token": "$2a$12$8dQf7X3PJa.FI6WizlfQ3eAmVK1/T9T4tSG1tyUqiuoQFn7zdRYYW", 

"refresh_token": "$2a$12$8dQf7X3PJa.ghljksadgfoy7gt8bhh7h7hSG1tyUghkdshkjasdhkdYW",

"token_type": "BEARER",
"expires_in": 315359999
}

Using the Refresh Token

The access token expires, and then the refresh token is used to generate a new access token.

  1. Send HTTP Post request to the /token end point with parameters:
    1. grant_type = "refresh_token"
    2. refresh_token set to the actual token from above
    3. HTTP Header
      1. Authorization - base 64 encoding of client id and secret, but the secret is not checked, eg Basic UG9zdG1hbjpzZWNyZXQ= 
  2. Assuming the refresh token is valid, you will get a response like the example shown below.
  3. Return the access_token in the header of requests, to be used as before

Base64 Encoding

On UNIX, you can use the printf command to do this quickly, the format is printf <username>:<password> | base64. For example:

Base64 encoding of AUTOTEST

printf AUTOTEST: | base64

QVVUT1RFU1Q6


or


printf ERIC:eric | base64

RVJJQzplcmlj

To use the OAuth secret as an OAuth2 secret

Generate the secret as in 1.a above, then copy it into OAUTH2_CLIENT using SQL similar to this:

Add OAUTH2 secret
insert into OAUTH2_CLIENT( client_id, client_secret, REDIRECT_URI, grant_types)
select app_name, secret, callback_url, 'token' 
from OAUTH_CONSUMERS 
where app_name = <whatever you supplied>

Note: In order to connect to ServiceNow in all AgileAssets versions including 7.5 and later, you will need to remove all the parameters from the URL and put an Authorization HTTP Header with the value as the following:

OAuth oauth_consumer_key="uRrVYh0vCxx43JdYXvSAgS0QsszO", 
oauth_signature_method="PLAINTEXT", 
oauth_signature="CustomerService1, 
oauth_timestamp="1509463000", 
oauth_nonce="FvxnpJeSe531", 
oauth_version="1.0"