rest api authentication icon

REST API authentication options with Spring Boot – Basic and Digest

When building your API, one of the most important things to consider is security. In this post, I discuss various REST API authentication options which can be implemented using Spring Boot. Spring Boot is a great choice for implementing REST API in Java, and one of my favorite frameworks. By leveraging Spring Boot, we can easily implement  various authentication options for our REST API.

REST API authentication options which we will discuss here are stateless. This means that server does not keep session information for clients, but rather authenticates each request as it comes in. This allows the server to handle much higher number of simultaneous users, because more memory is available for handling connections.

REST API authentication schemes

Generally, the following authentication schemes are widely used:

  • HTTP Basic authentication – this is the simplest authentication, and the least secure. It is part of the HTTP protocol and quite easy to implement
  • HTTP Digest authentication – more secure and more complex then Basic authentication. Digest is also part of HTTP protocol specification.
  • JWT (Json Web Token) – uses JSON to store client information and encrypts it with strong encryption cipher. JWT has recently gained popularity as authentication scheme
  • OAuth – OAuth uses third party to authenticate users and allow them access to certain resources. It is also quite popular approach for authentication, since it basically offloads the burden of authenticating clients to third party systems. OAuth2 is the current recommended version

In the rest of this post, I will show simple implementation of Basic and Digest authentication to protect your REST API. We will build simple Spring Boot application which requires authentication to access it’s resources. Source code for this application is available on Github.

In the next post, I will cover OAuth and JWT.

HTTP Basic as REST API authentication scheme

We’ll start from the simplest authentication scheme, HTTP Basic. This scheme requires each incoming request to have and Authorization  header. Header value must be similar to this example:

Client concatenates username and password with a single colon (:), and then encodes the resulting string as Base-64.

To implement this scheme in Spring Boot, we will use a filter which will  intercept incoming requests for protected resource. Let’s first create a controller which will show some message

When you invoke this endpoint, it will return simple message. Now, we want to require authentication for users who want to access this resource. We will implement simple filter for this feature:

Filter method is simple. First, it will check for Authorization  header in the incoming request. If header is not present, it will return a response with 401 status code, and WWW-Authenticate  header. In the value of WWW-Authenticate header, we specify authentication scheme and security realm. This response will cause the browser to display the following login window:

http authentication basic window

In our filter, we hard code the value for username and password. In real world, you would use something like a database to check login credentials, but for the purposes of demonstration, we’ll go with simple approach. Once user enters his credentials, filter will verify it, and if they match, user can access the resource. If credentials do not match, server will once again return the response for authentication challenge.

Pros and cons of HTTP Basic authentication

As you can see, Basic authentication is very simple and easy to implement. It is also supported by HTTP clients (eg. browsers), so it’s widely spread. On the other hand, it gives you almost zero security on it’s own. User credentials are encoded in Base64, and can be trivially decoded. So, Basic authentication can be safe only when used over SSL secured connection. In this case, SSL encrypts the data, so it adds a layer of security over plain Basic authentication.

In summary, you should generally avoid Basic authentication and use more modern and secure method, such as OAuth or JWT. More on this in the next post on this topic.

HTTP Digest as REST API authentication scheme

Digest authentication is more secure version of Basic authentication. It uses MD5 hashing algorithm to encrypt user credentials for safe transfer. In a nutshell, Digest authentication works as follows:

  1. Client requests web resource which requires security credentials, but does not provide credentials
  2. Server send a response with 401 HTTP status and header WWW-Authenticate . Value of this header contains several components, such as realm and nonce. Nonce is a randomly generated value which is used to enhance security of encrypted credentials
  3. Browser displays login window in which user enters username and password
  4. Browser send encrypted credentials, along with other information, so server can verify identity of the user
  5. If identity verification is successful, server allows access to resource. Otherwise, the process is repeated

This is somewhat simplified over, but it gives the basic idea. To further explain how credentials are encrypted, lets suppose that servers returns the following data as WWW-Authenticate  header:

Here you can see the example of nonce. It is a random string which server generates for each client. It is used as kind of salt for calculating hash of credentials. As a response to this challenge, client will respond with the following:

Main thing to consider here is the value of response. It is calculated in the following way:

  1. HA1=MD5(username:realm:password)
  2. HA2 = MD5(GET:uri)
  3. response = MD5(HA1:nonce:nc:cnonce:qop:HA2)

HTTP Digest implementation in servlet filter

As with Basic authentication, we will create a resource which we will protect by authentication. This is just simple controller method:

Without the filter, this resource can be accessed without problems by anybody. Now, we will add filter which will require credentials for login:

Just like with Basic authentication, filter will first check for existence of Authorization  header. If it does not exist, server will return a response with WWW-Authenticate  header. This header contains values which represent parameters for Digest authentication. Browser will use these value to produce correct values for authentication credentials.

Once browser receives this response, it will  show a window prompting a user for username and password. Once user enters credentials, browser will calculate parameters for Digest authentication and set them as a value for Authorization  header.

Back in the filter, it will first parse the value from Authorization  header. Then, it will calculate HA1, HA2 and response values as we described in previous section. If these values match expected, request passes through. Otherwise, server will prompt for authentication again.

Final word

Basic and Digest authentication are simple to implement and supported by all HTTP clients. The drawback is that they are not really secure, especially when used over plain HTTP connection. More modern and recommended ways for REST API authentication is to use OAuth or JWT. We will cover these two in the next post.

 

Leave a Comment

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