Dropwizard Basic Authentication Tutorial

Dropwizard Basic Authentication Tutorial

Introduction

        I am assuming that you have a Basic Knowledge of Dropwizard and have a Basic Dropwizard Application running in your machine. If not, please check my blog on Basic Dropwizard Application by going to the link: Dropwizard Tutorial

In this tutorial, we will be creating a Dropwizard Application with Basic Authentication (Username and Password Based Authentication) for the RESTful APIs.

Requirements to Run the Application:
  1. Java
  2. Maven
  3. IDE of your choice
Once you have a Basic Dropwizard Application, here are the additional steps required to add Basic Authentication for the RESTful APIs.

Step 1: Dropwizard Auth Module Maven Dependency to be added in pom.xml. 

Here is the dependency:

  <dependency>
   <groupId>io.dropwizard</groupId>
   <artifactId>dropwizard-auth</artifactId>
   <version>${dropwizard.auth.version}</version>
  </dependency>
In this tutorial we have used Dropwizard Auth Version: 0.8.1

Here is the full pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.aj.dropwizardbasicauth</groupId>
 <artifactId>DropwizardBasicAuth</artifactId>
 <version>1.0.0</version>


 <properties>
  <dropwizard.version>1.1.2</dropwizard.version>
        <dropwizard.auth.version>0.8.1</dropwizard.auth.version>
        <swagger.version>1.5.3-M1</swagger.version>
        <jdk.version>1.8</jdk.version>
  <packaging>jar</packaging>
 </properties>

 <dependencies>

  <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>

  <!-- https://mvnrepository.com/artifact/io.dropwizard/dropwizard-auth -->
  <dependency>
   <groupId>io.dropwizard</groupId>
   <artifactId>dropwizard-auth</artifactId>
   <version>${dropwizard.auth.version}</version>
  </dependency>

        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger.version}</version>
        </dependency>

 </dependencies>

 <build>
  <plugins>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.0</version>
    <configuration>
     <source>1.8</source>
     <target>1.8</target>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
     <createDependencyReducedPom>true</createDependencyReducedPom>
     <filters>
      <filter>
       <artifact>*:*</artifact>
       <excludes>
        <exclude>META-INF/*.SF</exclude>
        <exclude>META-INF/*.DSA</exclude>
        <exclude>META-INF/*.RSA</exclude>
       </excludes>
      </filter>
     </filters>
    </configuration>
    <executions>
     <execution>
      <phase>package</phase>
      <goals>
       <goal>shade</goal>
      </goals>
      <configuration>
       <transformers>
        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
         <mainClass>com.aj.dropwizardbasicauth.DropwizardBasicAuthApplication</mainClass>
        </transformer>
       </transformers>
      </configuration>
         </execution>
        </executions>
       </plugin>
      </plugins>
     </build>
    </project>
    

Step 2: Add ApplicationUser Object for which credentials have to be given in the API request

It is a basic object Java class. Here is the code:

package com.aj.dropwizardbasicauth.domain;

public class ApplicationUser {
}


Step 3: Authenticator Class

This class will verify the username and password in the Basic Auth Header. This class implements the interface io.dropwizard.auth.Authenticator. For simplicity, I am using Username and Password from yml file to authenticate the user. You can come up with your own strategy to store and retrieve password in your application. Here is the code:

package com.aj.dropwizardbasicauth.util;

import com.aj.dropwizardbasicauth.DropwizardBasicAuthConfiguration;
import com.aj.dropwizardbasicauth.domain.ApplicationUser;
import com.google.common.base.Optional;

import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials;


public class SimpleAuthenticator implements Authenticator<BasicCredentials, ApplicationUser> {

    private static String apiUsername;
    private static String apiPassword;

    public SimpleAuthenticator(DropwizardBasicAuthConfiguration basicAuthConfiguration){
        this.apiUsername = basicAuthConfiguration.getApiUsername();
        this.apiPassword = basicAuthConfiguration.getApiPassword();
    }

    @Override
    public Optional<ApplicationUser> authenticate(BasicCredentials credentials) throws AuthenticationException {
        if (apiUsername.equals(credentials.getUsername()) && apiPassword.equals(credentials.getPassword())) {
            return Optional.of(new ApplicationUser());
        }
        return Optional.absent();
    }
}

In the yml file, apiUsername and apiPassword are specified. I have used them in the Authenticator Class given above. Here is the file: dropwizardbasicauth.yml:

logging:
  level: INFO
  
  appenders:
    - type: console
      threshold: ALL
      timeZone: IST
      
server:
  type: simple
  applicationContextPath: /
  adminContextPath: /admin
  connector:
      port: 4000
      type: http

appName : DropwizardBasicAuth

apiUsername : login

apiPassword : logic

Step 4: Add Auth to API

io.dropwizard.auth.Auth support is added to RESTful API. Here is the API code:

    
    @Timed
    @POST
    @Path("/auth")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "API with Basic Authentication", notes = "Get Response if credentials are correct")
    public Response auth(@Auth ApplicationUser applicationUser, PingRequest pingRequest) throws Exception {
        logger.info("Request received is: " + pingRequest );
        Map<String, String> response = new HashMap<>();
        response.put("message", "");
        if("ping".equalsIgnoreCase(pingRequest.getInput())) {
            response.put("message", "pong");
        }
        return Response.ok(response).build();
    }

Project Setup:

For Java Setup, please refer to:  Java Setup
For Maven Setup, please refer to: Maven Setup
For Git and Project Setup, please refer to: Git and Project Setup

Run Application:

1. To run application in your IDE use:
    Program arguments: src/main/resources/dropwizardbasicauth.yml



2. To run JAR from command prompt:
     Build jar by using command:
     mvn clean install
     Run JAR by using command in Project folder location:
     java -jar target\DropwizardBasicAuth-1.0.0.jar src\main\resources\dropwizardbasicauth.yml

API calls and results:

1. POST API with Authentication for Ping:
http://localhost:4000/ping/auth
JSON Request Body:
{
"input": "ping"       }
Username: login
Password: logic




Other than this API, this application also has the following APIs:

1. GET API for Application Health Check:
http://localhost:4000/admin/healthcheck

2. GET API for Ping:
http://localhost:4000/ping

3. POST API for Ping:
http://localhost:4000/ping
    JSON Request Body:
  {
    "input": "ping"
  }

Conclusion and GitHub link:

   This tutorial gives an introduction to Dropwizard Basic Authentication which can be used to secure your RESTful APIs. The code used in this post is available on GitHub.
    Learn the most popular and trending technologies like Machine Learning, Angular 5, Internet of Things (IoT), Akka HTTP, Play Framework, Dropwizard, Docker, Elastic Stack, Spring Boot and Flask in simple steps by reading my most popular blog posts at Software Developer Central.
    If you like my post, please feel free to share it using the share button just below this paragraph or next to the heading of the post. You can also tweet with #SoftwareDeveloperCentral on Twitter. To get a notification on my latest posts or to keep the conversation going, you can follow me on Twitter. Please leave a note below if you have any questions or comments.

Comments

Popular Posts

REST API using Play Framework with Java

Asynchronous Processing (@Async) in Spring Boot

Elasticsearch, Logstash, Kibana Tutorial: Load MySQL Data into Elasticsearch