Intellij HTTP client: semi-automatic authentication

I’m a fan of the http client delivered as part of Intellij and I have been using it in many customer projects to quickly invoke service endpoints. Implementing requests is often faster than using other standalone tools like Postman and since it’s part of my prefered IDE there’s almost no friction using it.

Service endpoints often require authentication using JWT tokens provided by an OAuth server. But with every new project I have to lookup how to integrate the access token returned by an authentication request with subsequent service requests. So while I hope this post can be helpful to someone else, it is mainly for my own benefit.

Request environments

Most services run in different environments, for example you could have a DEV, UAT and PROD environment. You want to be able to target your request at different environments and the Intellij http client can manage these environments for you. These environments define a set of variables that can be used in our requests. For our example, we’ll have environment dependent hostnames for the OAuth server providing access tokens and the service itself. We’ll define environments while writing our http requests.

The authentication request

We already know that we need to obtain an access token. We have the URL for an OAuth server with all the parameters that we need, so this is how our request could look like:

POST https://dev-oauth.example.com/oauth/token?grant_type=client_credentials
Content-Type: application/json

First we tell the http client to use POST as the http method, then we specify the URI to connect to. The second line sets up the Content-Type header. Intellij will show a little green Run button alongside the request to execute it. If everything work correctly, the response will look something like this:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlciI6 ...",
"token_type": "bearer",
"expires_in": 399,
"asc": "generic:anonym",
"exp": 1681292845
...
}

We are interested in the access token property of the response. We could just copy it manually and use it in the Authorization header of subsequent requests, but we can automate this with a script that you add to the http request file.

> {%
var access_token = response.body['access_token']
client.global.set("access_token", access_token)
%}

This copies the access token to a global variable that can be used in subsequent requests.

Not let’s extract the oauth server url to an environment, after all our prod setup will use a different authentication server. At the top of the http file is a little menu “Run With” with “No Environment” as a value. If you click on the menu you can select Add Environment to Public File. Intellij will then create a new file called http-client.env.json (or open an existing one) where you can define your environment. We’ll add the dev environment for now and add the oauth server url:

"dev": {
"oauth-host": "dev-oauth.example.com"
}

This defines a variable called oauth-host that we can use in our authentication request. The request will then look like this:

POST https://{{ oauth-host }}/oauth/token?grant_type=client_credentials
Content-Type: application/json

Using the access token

Now let’s create a sample service request that uses the access token. It looks a lot like the example above.

GET https://{{ service-host }}/hello-world
Authorization: Bearer {{ access_token }}

In the meantime we also added the service-host variable to the dev environment, so we can use it here. The service request requires that we send the access token using the Authorization http header and we have stored it in a global variable before. By referencing that variable Intellij will substitute it. Once an access token has expired, we need to rerun the authentication request or we will get authentication errors.

SSL client certification

Here’s a special case that I encountered recently: the OAuth server required me to use an SSL client certificate in order to communicate. You can configure the http client to use a client certificate by adding a private environment file and adding this configuration to it:

"dev": {
"SSLConfiguration": {
"clientCertificate": "dev.pem",
"clientCertificateKey": "dev.key.pem",
"hasCertificatePassphrase": true
}
}

For every available environment you’ll define which certificate and which private key to use. If the private key is encrypted, you’ll need the addition hasCertificatePassphrase option. Intellij will then ask you for the password.

Leave a Reply

Your email address will not be published. Required fields are marked *