Understanding Authentication and Authorization in Dropwizard App (Kotlin)

Ron Paz
codeburst
Published in
5 min readNov 22, 2020

--

Photo by JJ Ying on Unsplash

Do you know how to perform authentication and authorization in Dropwizard? Neither did I, but I had to learn it for a recent project and I thought to share what I have learned with you.

Authentication

Authentication is used in order to identify who the user is. There are several authentication schemes that are used by the HTTP authentication framework.
In this post, we will talk about the “Basic” authentication schemes for simplicity. An important note: In the basic scheme, the user ID and password are passed in base64-encoding over the network. HTTPS/TLS should be used if you are using this scheme.

The Basic scheme flow:

Basic scheme flow
  1. The client tries to access a server resource through HTTP GET.
  2. The server sends a 401 Unauthorized response along with WWW-Authenticate header, which defines the authentication method. In our case, the authentication method is “Basic”.
  3. The client can trigger HTTP GET including an Authorization header with the credentials, in order to authenticate.
  4. In this step there are three options:
  • The server will send HTTP 200 OK, which indicates that the authentication has succeeded.
  • The server will send HTTP 401 Unauthorized response again, which means the credentials were wrong.
  • The server will send HTTP 403 forbidden. In this case, the user authenticated successfully but does not have the right permissions in order to access the resource.

You can find the official HTTP/1.1 Authentication documentation in RFC-7235

Authorization

We use authorization to manage the user’s permissions in our app. This is the process of granting or denying access to a resource based on the user’s identity. For example, if we want to create an API for user deletion, we would probably like to give permission for this API just for the admin of the system, and not for a regular user.

The relevant error status code is 403 Forbidden. When a 403 is sent, authentication is possible, but the user does not have the right permissions.

How to Implement Authentication and Authorization in the Dropwizard App

I believe it is easier to understand how all of these things work through a real example, so let’s start implementing authentication and authorization from scratch in our Dropwizard app with Kotlin. I assume you know how to create a Dropwizard app, if not you can read my previous post “Create an app with Dropwizard, Maven and Kotlin”.

POM Dependency

In order to use the Dropwizard authentication, you should add the following dependency to POM file:

Defining User Roles

Define an enum which represents the user role:

Implementing the Principal Object

Once the user is authenticated, the application establishes the Principal. The Principal is an object which represents the currently-logged-in user in the context of the application. One user can have multiple IDs, for example, if the user has several Gmail accounts. However, there is usually just one logged-in user per request and this is going to be the Principal.

We will implement a java.security.Principal interface as follows:

Creating a Custom Authenticator

Now we can create our authenticator which implements Interface Authenticator<C,P extends Principal>. The authenticator gets the user basic credentials as input and should validate them. If the authentication succeeds, the authenticate function should return a Principal object (the user) in an Optional container. Otherwise, an empty Optional is returned, indicating that the credentials are invalid. Here is the implementation:

Please note: this is a simple authenticator implementation just for demonstration.

Creating a Custom Authorizer

Our authorizer should implement the Interface Authorizer< P extends Principal >, which has a single method “authorize” that gets a Principal (user) and role, and is responsible for deciding if access is granted to this Principal.

Authenticator and Authorizer Registration

We are ready to register the custom authenticator and authorizer in our Dropwizard app.

AuthDynamicFeature enables HTTP basic authentication.
RolesAllowedDynamicFeature enables HTTP authorization.
AuthValueFactoryProvider allows you to use @Auth to inject a custom Principal type into your resource. In this example, we are using BasicCredentialAuthFilter which supplies us with an out-of-box authentication filter (implementation of AuthFilter). It is possible to define a custom filter if needed. To do that you should use AuthDynamicFeature and implement the AuthFilter Dropwizard class.

Secure Our Resources

There are two options to secure your resource:

  1. Use one of @RolesAllowed, @DenyAll, @PermitAll annotations. Each of these annotations will trigger the authenticator and the authentication filter to validate the credentials, and the authorizer, to check the permissions.
  2. Use @Auth annotation, in order to trigger the authenticator and the authentication filter.

An important note: Using @PermitAll and not setting any of these annotations is not the same! If you don’t set one of these annotations, the authenticator will not be triggered, so any user can access this API.

Testing our security

Let’s access our application in the browser through http://localhost:port/helloWorld. In the IntelliJ terminal, you can see that the server sent GET /helloWorld HTTP/1.1" 401 as described in the flow diagram (step 2). You should see a sign-in dialog box where you can enter a username and password to authenticate. Let’s try to enter different credentials to see what happened:

  • Try entering the wrong credentials. You should get another HTTP 401 Unauthorized error, which indicates an authentication failure.
  • Try entering guest credentials. You should get an HTTP 403 Forbbiden, as we defined @RolesAllowed("Admin") on our resource.
  • Finally, we can enter the admin credentials. You should get 200 OK status code. Looking at the HTTP request header (click F12 in the browser), we can see the following Authorization header:
    Authorization: Basic QWRtaW46c2VjcmV0

The Basic stands for the HTTP Basic schema, and the string QWRtaW46c2VjcmV0 represents the credentials in base64-encoding. We can use a base64 encoder, and we will get the credentials we entered: Admin:secret

Conclusion

So there you have it, how to perform authentication and authorization in Dropwizard! As mentioned earlier, this was something that I was unfamiliar with originally. I hope that this post is able to help you understand the concept I laid out. Thanks for reading.

--

--