Understanding Authentication and Authorization in Dropwizard App (Kotlin)
By: Ron Paz
Tags: Security, Web Development, Authentication, Backend, Kotlin

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 Principle Object

Once the user is authenticated, the application establishes the Principle. The Principle 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 Principle.

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 Principle 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 Principle (user) and role, and is responsible for deciding if access is granted to this principle.

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:

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. 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.

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.