Authentication

Most APIs have some form of security (authentication and authorization). Specmatic reads OpenAPI Security Schemes in your API Specifications to come up with appropriate request parameters.
Specmatic supports the following security schemes:

  • OAuth2
  • API Key
  • Bearer

Testing with real auth

To run contract tests in environments which require a valid security token present in the request, we can define environment variables which hold these valid tokens/api keys.

The enviornment variable should match the name of the security scheme defined in the open api specification.

When contract tests are executed, Specmatic will look for an environment variable with the same name as that of the security scheme. If such an environment variable exists, Specmatic will use it apporpriately (based on the security scheme) while making an HTTP request.

OAuth2

Here’s an example of an OAuth2 security scheme in the open api specification:

components:
  securitySchemes:
    oAuth2AuthCode:
      type: oauth2
      description: For more information, see https://example.com/docs/oauth
      flows:
        authorizationCode:
          authorizationUrl: https://api.example.com/oauth/authorize
          tokenUrl: https://api.example.com/api/oauth/token
          scopes:
            users:read: Read user information
            users:write: Modify user information
            im:read: Read messages
            im:write: Write messages
            im:history: Access the message archive
            search:read: Search messages, files, and so on

To use a real OAuth2 token in contract tests, an environment variable with the name of the security scheme needs to be defined.

For example, in the above case, we would define an environment variable named oAuth2AuthCode. Assuming that Authorization header value has to be Bearer abc123, set the value of this environment variable to abc123 (leaving out the Bearer prefix).

API Key

Here’s an example of a Bearer security scheme in the open api specification:

components:
  securitySchemes:
      ApiKeyAuthHeader:
        type: apiKey
        in: header
        name: X-API-KEY

To use a real API key header in contract tests, an environment variable with the name of the security scheme needs to be defined.

For the above example, define an environment variable named ApiKeyAuthHeader having the API key as it’s value.

For example, in the above case, we would define an environment variable named ApiKeyAuthHeader. Assuming that Authorization header value has to be my-api-key-abc123, set the value of this environment variable to my-api-key-abc123.

Bearer

Here’s an example of a Bearer security scheme in the open api specification:

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

To use a real bearer auth token in contract tests, an environment variable with the name of the security scheme needs to be defined.

For example, in the above case, we would define an environment variable named BearerAuth. Assuming that Authorization header value has to be Bearer abc123, set the value of this environment variable to abc123 (leaving out the Bearer prefix).

Basic Authentication

Here’s an example of a Bearer security scheme in the open api specification:

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

To use a real basic auth token in contract tests, an environment variable with the name of the security scheme needs to be defined.

For example, in the above case, we would define an environment variable named BasicAuth. Assuming that Authorization header value has to be Basic abc123, set the value of this environment variable to abc123 (leaving out the Basic prefix).

Testing with mock auth

While Specmatic supports testing with real authentication as seen above, in a component / contract test like setup, it is recommended to isolate the SUT (System Under Test) which is your service from other dependencies such as auth providers. So at a contract / component test level it is sufficient to validate if an API implementation / service accepts the security parameters it is adverstising in its API Specification. However it is not necessary to validate if the security itself is working. That is for later stages of tests where you can hook up a security service dependency such as DB, OAuth provider, etc.

So for Contract as Test we recommend having a “Test Security Configuration” where you are still exercise your security plumbing, however not actually fetching real user information. This is similar to running an in-memory DB in test setup instead of running a real DB in CI. Below are some examples of the same.

OAuth2

Please refer to this sample API specification which leverages OAuth2 to protect all endpoints that add, modify or delete data.

Wiring up dummy / mock authentication

Specmatic Sample Application to demonstrate OpenAPI OAuth2 security scheme support

Please refer to sample springboot application that implements the API we saw above.

API Key Authentication

Please refer to this sample API specification which leverages ApiKeyAuth to protect all endpoints that add, modify or delete data.

Wiring up dummy / mock authentication

Please refer to sample springboot application that implements the API we saw above.

This has two API security configurations

  • Production Security Config - This fetches user from the DB based on api token in request header
  • Test Security Config - This always returns a dummy user principal. However rest of the code such as reading the authentication token from header etc. are still tested.

So when you run the ContractTest it will still exercise your security plumbing (does the application accept the proper header name, datatype, etc.).

This is just an example of how we can wire up security configurations for test and production environments. Even in SpringBoot you can leverage other techniques such as Spring Profiles to achieve the same effect.

The same can be achieved in almost any programming language and stack.

  • Dot Net - Register a custom AuthenticationHandler for mock authentication in tests
  • NodeJS - Switch auth middleware based on process.env.NODE_ENV

In general the overall idea is to inject a mock authentication mechanism while running Specmatic Contract as Tests