In this section:
Introduction
The OAuth (Open Authorization) authentication protocol enables users to grant third-party applications access to their private resources without revealing login credentials. It also provides a way to restrict the amount of information that can be accessed.
OAuth introduces the user role (also known as the resource owner) into the traditional client-server authentication model. In the traditional client-server authentication model, the client directly accesses resources hosted on the server. In the OAuth model, the client must first obtain permission from the resource owner before accessing resources from the server. This permission is expressed in the form of a token and matching shared-secret key.
OAuth 2.0 and 1.0a are different implementations and are incompatible. Refer to the OAuth website to learn more: https://oauth.net/2/.
Example Scenario
Assume that a user (resource owner) wants to grant a printing service (client) access to his private photos stored at a photo sharing service (server). Instead of revealing the user's login credentials to the printing service, the user can perform OAuth authentication to grant the printing service permission to access his or her private photos. This would happen in three stages:
- The printing service requests temporary credentials from the photo sharing service.
- Once the printing service receives the credentials, it redirects the user to the photo sharing service's OAuth Authorization URL, then the user provides login credentials. Note that the printing service has no visibility into the user's login credentials at this step. Once the user decides to give the printing service access to the private photos, a confirmation verification code is generated.
- The printing service then exchanges the temporary credentials plus the verification code for an access token. Once the printing service has the access token, they can then obtain and print the user's private pictures from the photo sharing service.
Parasoft Support for OAuth
Parasoft supports OAuth 1.0a and 2.0 security protocols for web server flow and client credentials flow (two-legged scenario). Configuring authentication using OAuth 1.0a and OAuth 2.0 is described below.
OAuth 2.0
The OAuth 2.0 RFC specifies different "flows" or "grant types" for authentication. This documentation describes how to use the three most common flows with SOAtest: the web server (authorization code) with or without PKCE and client credentials.
See https://oauth.net/2/grant-types/ for additional information about OAuth 2.0 flows.
Web Server (Authorization Code) Flow
This grant type is used by confidential and public clients to exchange an authorization code for an access token. After the user returns to the client via the redirect URL, the application will get the authorization code from the URL and use it to request an access token. Refer to the OAuth 2.0 Framework documentation for details about this flow: https://tools.ietf.org/html/rfc6749#section-4.1
To set this up in SOAtest, you will first need to create a test scenario that gets an authorization code to use as a login suite. This login suite, in turn, is called by test scenarios that need a token. The procedure is the same whether you are using an authorization code with Proof Key for Code Exchange (PKCE) or not, though if it is with PKCE there are a couple extra variables that will need to be configured.
Create a Login Test Suite
- Right-click on your project folder and choose Add New > Test (.tst) File.
- Specify a name for the test and choose Web > Record web scenario.
- Click Next and choose Record new web scenario.
- Enter the URL for the authorization endpoint URL in the Start Recording From field and click Next.
- Do not use the URL of the application under test (AUT), even though it automatically redirects to the authorization endpoint (that is, the login page). You want to use the URL for the authorization endpoint itself, otherwise the AUT will consume the token before you have a chance to use it in your test.
- Enable Add URL variable to your existing environment and click Finish. The login page for your application opens.
- Log into your application. Once authorized, the Service Provider will redirect you to the callback URL with a code as part of a URL parameter.
- Close the browser to complete the recording.
- Run the test once to populate the tests with traffic.
- Right-click on the test node that contains the login action (this will vary depending on your login procedure, but is usually the last test in the recorded scenario) and choose Add Output..., then enable HTTP traffic.
- Click Next and select the redirected URL containing the access code.
The request URL will look different depending on the application used. For Azure AD, for instance, the request URL start with something like https://login.microsoftonline.com/kmsi, while for Keycloak the request URL will look something like https://localhost:8443/auth/realms/my-realm/login-actions/authenticate. In any case, the URL will contain the
?code=
parameter followed by the access code.
- Click Next and choose Response: Header > Text Data Bank to extract the code.
- Click Finish and run the test again to populate the text data bank.
- Open the text data bank and, in Text Content, find the redirect location containing the code (usually in a "Location" header). In that URL you should find the authorization code (preceded by the "code=" parameter). Select that code and click Create Extraction from Selection. Name it
OAUTH2_AUTHORIZATION_CODE
and click OK. - Optional: Parameterize the authorization endpoint. Setting the parameters of the authentication endpoint in the login suite makes it more adaptable. To do so:
- Open the test in the recorded scenario that navigates to the authorization endpoint (this is usually the first test) and click the User Action tab.
In the URL field, change the following parameters from their static values to the specified variables, as applicable:
Parameter Variable client_id ${OAUTH2_CLIENT_ID}
redirect_id ${OAUTH2_REDIRECT_URI}
scope ${OAUTH2_SCOPE}
audience ${OAUTH2_AUDIENCE}
- If you chose
Authorization Code with PKCE
as the Grant Type, see the next step for additional parameterizing requirements.
- If you chose
- Save your changes.
- If you are using an authorization code with PKCE, the authorization endpoint must be configured to accept variables for the
code_challenge
andcode_challenge_method
parameters. To do so:- Open the test in the recorded scenario that navigates to the authorization endpoint (this is usually the first test) and select the User Action tab.
In the URL field, change the following parameters from their static values to the specified variables:
Parameter Variable code_challenge ${OAUTH2_CODE_CHALLENGE}
code_challenge_method ${OAUTH2_CODE_CHALLENGE_METHOD}
- Save your changes.
If you parameterized the authorization endpoint by setting one or more of the variables described above, but still want to be able to run the web scenario independently, you can set default values for parameterized values on the Variables tab. For more information, see "Defining Variables" on the Configuring Test Suite Properties - Test Flow Logic, Variables, etc. page.
Set up a Shared OAuth 2.0 Authentication for the Test Suite
- Right-click the test suite and choose Add New > Global Property...
- Expand the Authentication list, then choose OAuth 2.0 and click Next.
- Set the Grant Type to
Authorization Code
orAuthorization Code with PKCE
, as appropriate, and click Finish. The OAuth 2.0 authentication configuration screen opens. - Enter an easily identifiable name in the Name field.
- Configure the remaining settings as described below. If you chose to parameterize the authorization endpoint in the login suite, these settings will be used to acquire the proper OAuth 2.0 token. If you did not parameterize the authorization endpoint (or only parameterized some of it), be sure that the un-parameterized settings match those in the authorization endpoint URL exactly.
- Login Suite: Click Workspace and select the login suite created above.
- Redirect URI: Enter a redirect URI that will not consume the OAuth 2.0 token. This URI should be on the authorization server's whitelist of redirect URIs.
- Token URI: Enter the access token endpoint on the OAuth 2.0 authorization server.
- Client ID: Enter the client ID needed for authenticating with the authorization server.
- Client Secret: Enter the client secret needed for authenticating with the authorization server.
- Scope: This parameter is used by the client to request limited access to the application. A comma-separated list of values specific to the authorization server may be entered. See https://oauth.net/2/scope/ for additional information. If no scope is specified, the default scope may be returned.
- Audience: Enter the URI of the resource server.
- Code Verifier (Authorization Code with PKCE only): Select a method for generating the code verifier. By default, this is done automatically, which is recommended. The automatically generated code verifier will comply with OAuth 2.0 standards, being a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters - . _ ~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long. If you choose a different method, ensure that the result meets the same standards, or the token request might be rejected.
- Challenge Method (Authorization Code with PKCE only): Select whether the code challenge is the plain text version of the code verifier or the SHA-256 version of the code verifier.
- Select whether to send the access token using Header or Query Parameter.
- Save your configuration.
Create a Test Scenario
Right-click the project you want to create your test scenario in and choose Add New > Test (.tst) File. Finish creating this scenario as appropriate for your application and testing needs. If you already have a scenario that you want to use, you can skip this step.
Load Testing
If you intend to load test this scenario, you should configure the test suite to run the tests as a group (open the test suite and go to the Execution Options > Test Execution tab). If the test suite is configured with the "Tests are individually runnable" option enabled instead, each virtual user will run one of the tests in the suite in isolation, with no OAuth 2.0 access token reuse, and Load Test will have to repeatedly execute the login suite in order to get new access tokens.
- Right-click your test scenario and choose Add New > Test. Create a new REST Client in your test scenario, setting the Method to
GET
and the URL to your AUT. - If the shared authentication you created earlier is the only one created for this test suite, it will be used automatically. Otherwise, click Authentication under Security, then select Custom from the first dropdown menu in the Authentication pane and choose it.
- Run the scenario and confirm that the OAuth 2.0 token was acquired and used successfully.
Client Credentials Flow
This grant type is used by clients to obtain an access token outside of the context of a user. This is typically used by client applications to access resources about themselves rather than to access a user's resources. Refer to the OAuth 2.0 Framework documentation for details about this flow: https://tools.ietf.org/html/rfc6749#section-4.4.
Set up a Shared OAuth 2.0 Authentication for the Test Suite
- Right-click the test suite and choose Add New > Global Property...
- Expand the Authentication list, then choose OAuth 2.0 and click Next.
- Set the Grant Type to
Client Credentials
and click Finish. The OAuth 2.0 authentication configuration screen opens. - Enter an easily identifiable name in the Name field.
- Configure the remaining settings:
- Token URI: Enter the access token endpoint on the OAuth 2.0 authorization server.
- Client ID: Enter the client ID needed for authenticating with the authorization server.
- Client Secret: Enter the client secret needed for authenticating with the authorization server.
- Scope: (Optional) Specify the scope of the access token. If multiple parameters are needed, separate them with commas. See https://oauth.net/2/scope/ for additional information. If no scope is specified, the default scope may be returned.
- Audience: (Optional) Enter the URI of the resource server.
- Select whether to send the access token using Header or Query Parameter.
- Save your configuration.
Create a Test Scenario
- Right-click your test suite and select Add New > Test. Create a new REST Client in your test suite.
- Click the HTTP Options tab and choose either HTTP 1.0 or HTTP 1.1 from the Transport menu.
- If the shared authentication you created earlier is the only one created for this test suite, it will be used automatically. Otherwise, click Authentication under Security, then select Custom from the first dropdown menu in the Authentication pane and choose it.
- Click the Resource tab and specify your REST call method and endpoint, including any expected parameters.
- The OAuth 2.0 access token will be automatically injected.
- Run the scenario and verify the expected HTTP request header that was sent. Example Authorization header:
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Load Test Considerations
If you intend to load test a scenario, you should enable "Tests run as a group" in its parent Test Suite (which can be found on the Execution Options > Test Execution tab). This option allows each virtual user (VU) to run the entire scenario, so each VU is able to acquire and reuse its own OAuth 2.0 access token. If "Tests are individually runnable" is enabled instead, each VU will run one of the tests from the suite in isolation with no access token reuse, with each test acquiring its own token, which will result in repeatedly executing the Login suite in order to get new access tokens.
Troubleshooting
Errors relating to OAuth 2.0 can be generally sorted into two types: an error getting the OAuth 2.0 authorization code or an error getting the access token. Before you begin to troubleshoot, review the errors in the Quality Tasks view to determine which type of problem you're having.
If the problem is getting the authorization code:
- Try running the Login suite directly to make sure it works as expected.
- If you parameterized the authorization endpoint in your Login suite, you can still run it independently by setting default values for parameterized values on the Variables tab. For more information, see "Defining Variables" on the Configuring Test Suite Properties - Test Flow Logic, Variables, etc. page.
- Check the Console view for messages while the test is running.
If the problem is getting the access token:
- Check the traffic associated with any OAuth 2.0 errors by right-clicking them in the Quality Tasks view and choosing View Associated Traffic.
OAuth 1.0a
Authenticating against OAuth 1.0a includes the following general steps:
- Obtain and authorize a request token from the service provider.
- Exchange the request token for an access token.
- Sign OAuth requests to access protected resources.
The following example uses the REST Client to send request messages to the server. You can alternatively use the Messaging Client in the same manner.
Obtain and Authorize a Request Token from the Service Provider
- Create a new REST Client and configure the settings for the location where the Request Token will be obtained.
- Click the HTTP Options tab and choose either HTTP 1.0 or HTTP 1.1 from the Transport menu.
- Click Authentication under Security.
- Select Custom from the first dropdown menu in the Authentication pane.
- If an OAuth 1.0 shared authentication configured to obtain a request token has been set for the test suite (see "Specifying Client Options" on the Configuring Test Suite Properties - Test Flow Logic, Variables, etc. page), you can select it from the second drop-down menu and skip to step 11.
- Click New, then select OAuth 1.0 and click Finish. An OAuth 1.0 authentication is added to the Authentications node for the test suite (if this is the first custom authentication added to the test suite, the Authentications node is created automatically).
- Enter an easily identifiable name in the Name field.
- Enter the consumer key and consumer secret in the Consumer Key and Consumer Secret fields.
- Choose "Obtain Request Token" from the Mode menu.
- (Optional) Specify a scope in the Scope fields.
- (Optional) Add additional OAuth parameters under Parameters.
- Attach a Text Data Bank to the Response Traffic of the REST Client and extract the Request Token and the Request Token Secret. The token is usually denoted as
oauth_token
. - Go to File > New > Test (.tst) File from the main menu and choose your project.
- Enter a name for the file and click Next.
- Choose Web > Record web scenario and click Next.
- Choose Record new web scenario and click Next.
- In the Start Recording From field, enter the URL to obtain the verification code. Add an
oauth_token
parameter and specify the value of the request token obtained in the step 10.
Once the browser launches, it will display the login page of the server that is hosting the protected resource. - Sign in by providing the user's login credentials (Username/Password). Once authorized, the browser will redirect you to a new page with a verification code.
- After you see the verification code, exit the recording by closing the browser.
- Attach a Browser Data Bank to the Browser Contents (rendered HTML) and extract the value of the verification code.
- Open the Browser Playback tool and replace the literal Request Token string with the Request Token data source column generated by the Text Data Bank (step 10). Use the
${varName
} syntax, as shown below.
Exchange the Request Token for an Access Token
- Create a new REST Client and configure the settings for the location where the Request Token should be exchanged for the Access Token.
- Click the HTTP Options and choose either HTTP 1.0 or HTTP 1.1 from the Transport menu.
- Click Authentication under Security.
- Select Custom from the first dropdown menu in the Authentication pane.
- If an OAuth 1.0 shared authentication configured to exchange the request token for an access token has been set for the test suite (see "Specifying Client Options" on the Configuring Test Suite Properties - Test Flow Logic, Variables, etc. page), you can select it from the second drop-down menu and skip to step 10.
- Click New, then select OAuth 1.0 and click Finish. An OAuth 1.0 authentication is added to the Authentications node for the test suite (if this is the first custom authentication added to the test suite, the Authentications node is created automatically).
- Enter the consumer key and consumer secret in the Consumer Key and Consumer Secret fields.
- Choose Exchange Request Token for Access Token from the Mode menu.
- Parameterize the Request Token and Request Token Secret fields from the Text Data Bank extractions.
- Parameterize the Verification Code field from the Browser Data Bank.
- Attach a Text Data Bank to the Response Traffic of the REST Client and extract the Access Token (usually denoted as oauth_token) and the Access Token Secret (usually denoted as oauth_token_secret).
Sign OAuth Requests to Access Protected Resources
- Create a new REST Client and configure the settings for the location where the Request Token should be exchanged for the Access Token.
- Click the HTTP Options and choose either HTTP 1.0 or HTTP 1.1 from the Transport menu.
- Click Authentication under Security.
- Select Custom from the first dropdown menu in the Authentication pane.
- If an OAuth 1.0 shared authentication configured to sign the request for OAuth authentication has been set for the test suite (see "Specifying Client Options" on the Configuring Test Suite Properties - Test Flow Logic, Variables, etc. page), you can select it from the second drop-down menu and skip to step 9.
- Click New, then select OAuth 1.0 and click Finish. An OAuth 1.0 authentication is added to the Authentications node for the test suite (if this is the first custom authentication added to the test suite, the Authentications node is created automatically).
- Enter the consumer key and consumer secret in the Consumer Key and Consumer Secret fields.
- Choose "Sign Request for OAuth Authentication" from the Mode menu.
- Parameterize the Access Token and Access Token Secret fields from the Text Data Bank extraction.
- Request the user's private resources. This should be possible because the Access Token has been obtained.