OAuth2 Migration Best Practices
Old World Authentication
- The old world authentication is a hybrid oauth2 implementation which has an endpoint that looks like this
/net2/oauth2/ - Client applications are identified by a
ConsumerKeyandSecretpair. Sometimes these are referred to asclient_idandclient_secret. - Access Tokens in the old world have a 12 months expiry period and refresh tokens live forever. This is typically not a good security practice and goes against the Oauth2 standards.
- Tokens that are being used by clients today are issued for WSADMINs, meaning all tokens have administrative access.
New World Authentication
Oauth2
- The SAP Concur new Oauth2 implementation follows the established Oauth2 Authorization Framework RFC : https://tools.ietf.org/html/rfc6749
- This new service has an endpoint of
/oauth2/v0/token - Unlike the old world auth, access tokens have a 1 hour expiry and refresh tokens have a 6 months expiry. This is in accordance to the best practice of using short lived tokens.
- This would mean that clients would need to perform token management.
Getting Started
- Getting clientID / clientSecret
- Work with the SAP Concur implementation team to obtain a new oauth2
client_idandclient_secretand to define the scope of client’s application. - Process will take no longer than 48 hours.
- Implementation Team will respond with new
client_id,client_secret, company’srefreshTokenandexpiry date. - Client stores and configures application with this info.
- Work with the SAP Concur implementation team to obtain a new oauth2
- Client applications should store the following tokens and data in their application.
Refresh Token: This token can change although most of the time this value is the same. Client applications should treat all returned refresh tokens as new values and overwrite the stored values with the new values you get from the response.Refresh Token Expiry: This date should be checked by a daily script and ensure that a refresh_grant is made to keep the refresh token alive indefinitely. If company policy dictates that the token should be allowed to expire, then you can skip this step. Once a refresh token has expired, clients would need to contact SAP Concur’s Implementation team to get a new company token.
Token Management
- Calling APIs with
accessTokens- All APIs within SAP Concur require the calling application present an
accessTokenin the Header using the “Bearer” keyword. - Example:
curl -k -v -H "Accept: application/json" \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjE0NTU2MTQzNDYifQ.eyJhdWQiOiIqIiwic3ViIjoiaHR0cDovL21zcGNzcHJzcnFhLmNvbmN1ci5jb25jdXJ0ZWNoLm9yZzozMDAzL3Byb2ZpbGUtc2VydmljZS92MS91c2Vycy83NjAwOUFEMy1GNzdCLTREOTgtQTIxQS01NTNDOUM5MTc5RjAiLCJpc3MiOiJodHRwczovL2NvbmN1ci5jb20iLCJleHAiOjE0NzM4OTUxMjksImxlZ2FjeV9hcHBsaWNhdGlvbl9pZCI6MTUwMDA2MzY1OSwidXNlclVSSSI6Imh0dHA6Ly9tc3Bjc3Byc3JxYS5jb25jdXIuY29uY3VydGVjaC5vcmc6MzAwMy9wcm9maWxlLXNlcnZpY2UvdjEvdXNlcnMvNzYwMDlBRDMtRjc3Qi00RDk4LUEyMUEtNTUzQzlDOTE3OUYwIiwidXNlcnV1aWQiOiI3NjAwOUFEMy1GNzdCLTREOTgtQTIxQS01NTNDOUM5MTc5RjAiLCJuYmYiOjE0NzM4OTE1MjksImh0dHBzOi8vYXBpLmNvbmN1cnNvbHV0aW9ucy5jb20vYXBwIjoiaHR0cHM6Ly9hcGkuY29uY3Vyc29sdXRpb25zLmNvbS9hcHAtbWdtdC92MC9hcHBzL2UwMTBlMjVkLWI0Y2UtNGNlMy1hN2U0LWI2NzBjYjFhZGNiMCIsImh0dHBzOi8vYXBpLmNvbmN1cnNvbHV0aW9ucy5jb20vc2NvcGVzIjpbIkNDQVJEIiwiQ09NUEQiLCJVU0VSIiwidXNlcl9yZWFkIiwiRU1FUkciLCJKT0JMT0ciLCJFUkVDUFQiLCJJVElORVIiLCJGSVNWQyIsIkxJU1QiLCJQQVNTViIsIkNPTkZJRyIsIkZPUCIsIkdIT1NUIiwiQ09OUkVRIiwiVFJJUElUIiwiQ09NUEFOWSIsInByb2ZpbGUiLCJFVlMiLCJlbWFpbCIsIlRSVlBUUyIsIkFUVEVORCIsIklOVlBPIiwiTk9USUYiLCJUUlZSRVEiLCJTVVBTVkMiLCJFWFBSUFQiLCJhZGRyZXNzIiwiRVhUUkNUIiwiUEFZQkFUIiwid3Jvbmdfc2NvcGUiLCJJTlZQTVQiLCJJTUFHRSIsIlRBWElOViIsIlJDVElNRyIsIlVOVVRYIiwiVFdTIiwiVE1DU1AiLCJCQU5LIiwiSU5WVkVOIiwib3BlbmlkIiwiTVRORyIsIklOU0dIVCIsIlRSVlBSRiIsIklOVlRWIiwiTUVESUMiLCJUU0FJIl0sImlhdCI6MTQ3Mzg5MTUyOX0.QHY4Mc5A3J981-HDv7KUdgS4tUI-qnmQAxwe9J6DHxuMmYSoGEYZ0dsnLnqc2lO2iVJK6Pg3EBZTArq8_vzV2FK7tA4-IT1eCEHo1e-RWZyWLnR7P56SvZozXpY73daovSH7572HrUm21FXcyLmdaLZyo2LfFcChaghbSCjm1Jg1duH-pLPUW4d89-_pdakmyxfV3GCm2N_XQXoRhNYAAiZcG8UfxEn3TpMHJ96F2n6keJanT_Sn2Sek_sH2EmeeCpg5-jDe0fvLvr1-gY5t0ifq8QBKWHSUUIrGbQvseD6CGzfyiFUqVypN2lukfWACR-26otN50c0OzY6kgY06RA" \ https://us.api.concursolutions.com/profile/v1/me - More documentation here: https://developer.concur.com/api-reference/authentication/getting-started.html
- All APIs within SAP Concur require the calling application present an
- Refreshing expired
accessTokens- Since
accessTokenshave a one hour expiry, clients would need to get a newaccessTokenbefore any API call is made. - In order to obtain a new
accessToken, clients should call Oauth2 using therefresh_grantand providing the oldrefreshTokenand other additional fields. -
In the error handling code, clients need to handle
accessTokenexpiry errors. If theaccessTokenis expired in the middle of processing, the following should happen:- Code should call Oauth2’s
refresh_grantto get a newaccessToken - Overwrite the existing
refreshTokenwith the new one. - Update
expiry dateforrefreshToken - Retry the API call.
- Code should call Oauth2’s
- More details about refreshing tokens here: https://developer.concur.com/api-reference/authentication/apidoc.html#refresh_token
- Since
- Handling errors
- There are a few error codes that client applications should be aware of.
403 Forbidden: Requesting for tokens for users who cannot be requested for. Usually for companies that are not authorized by their administrators.- The bulk of errors will be returned as 400 errors and the response contains a
codeanddescription. Client applications should look for these values to determine what to do next.
Code Desc Comment 05 Incorrect credentials. clientID / secret not correct, or authtoken/password not correct 10 Account is disabled 14 Account is locked 16 User lives elsewhere There will be a geolocation field in the response to this error message. Use this as the base URL and retry the call. 54 Invalid Scope requested scope exceeds what is permitted. - for a full list, review this doc: https://developer.concur.com/api-reference/authentication/apidoc.html#response_codes
Old auth v.s. new auth diagram
