User management microservice (Part 7): Putting it together

April 18, 2017 · 5 min read – Last updated on August 10, 2020

During writing the last six parts (Defining domain model and REST API, Implementing the domain model, Implementing and testing repositories, Implementing REST API, Authentication with JWT tokens and Spring Security, Remember me authentication with persistent JWT tokens) of this article series a lot has happened. From absolutely zero the building blocks of a user management application had been developed. In this last article, I’d like to show you how to assemble the pieces in order to get the app working. Some functionalities are still missing and I’m still working on the first release to make make it feature complete, but the very basics are available now.

1. Creating an self-contained, executable module

The easiest way to build Spring-based application today is to go for Spring Boot. There’s no doubt about that. It’s gaining massive adoption for one reason and that is that is makes your life a lot easier than working with bare Spring. I had worked with Spring in various scenarios before and built applications on top of servlet containers and fully fledged Java EE application servers as well, but being able to package everything in executable bundle eases development costs very much.

Having all the said the first step is to create a new module to the app, it’s springuni-auth-boot.

1.1. Maven configuration

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

  <parent>
    <artifactId>springuni-particles</artifactId>
    <groupId>com.springuni</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>springuni-auth-boot</artifactId>

  <name>CraftingJava Auth User Boot</name>
  <description>Example module for assembling user authentication modules</description>

  <dependencies>
    <dependency>
      <groupId>com.springuni</groupId>
      <artifactId>springuni-auth-rest</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
      <groupId>com.springuni</groupId>
      <artifactId>springuni-auth-user-jpa</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <!-- https://github.com/spring-projects/spring-boot/issues/6254#issuecomment-229600830 -->
        <configuration>
          <classifier>exec</classifier>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Module springuni-auth-rest provides the REST endpoints for user management and it also pulls springuni-auth-model as a transitive dependency. springuni-auth-user-jpa takes care of persisting user data and it will be replaceable with other persistence mechanisms in the future.

The third dependency is MySQL connector and that is also replaceable depending on the requirements.

From the point of view of Spring Boot, the following two dependencies have importance: spring-boot-starter-web and spring-boot-starter-tomcat. In order to be able to create a Web app, we need both of them.

1.2. Application’s entry point

Doing this step without Spring Boot would be laborious quite a bit (having to register context listeners in web.xml and setting up a container for the app).

import com.springuni.auth.domain.model.AuthJpaRepositoryConfiguration;
import com.springuni.auth.domain.service.AuthServiceConfiguration;
import com.springuni.auth.rest.AuthRestConfiguration;
import com.springuni.auth.security.AuthSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Configuration
@Import({
    AuthJpaRepositoryConfiguration.class,
    AuthServiceConfiguration.class,
    AuthRestConfiguration.class,
    AuthSecurityConfiguration.class
})
public class Application {

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }

}

This is pretty much an dummy module and the all the heavy lifting it has to do boils down to having to import some Java-based Spring configuration classes.

1.3. Starting up

Spring Boot comes with a very useful Maven plugin which is able to repackage the whole project as a self executable über JAR. It’s also capable of starting the project up locally.

mvn -pl springuni-auth-boot spring-boot:run

2. Test drive the user management app

The first part defined all the available REST endpoints and now time has come to test them with some real-world use cases.

2.1. Register a new user

curl -H 'Content-Type: application/json' -XPOST http://localhost:5000/users -d \
'{
 "screenName":"test2",
 "contactData": {
   "email": "test2@craftingjava.com"
 },
 "password": "test"
}'
HTTP/1.1 200

2.2. First login attempt

Out first login attempt should inevitably fail at this point, as the user’s account hasn’t been confirmed yet.

curl -D- -XPOST http://localhost:5000/auth/login -d '{ "username":"test5", "password": "test" }' 
HTTP/1.1 401 
{
 "statusCode" : 401,
 "reasonPhrase" : "Unauthorized"
}

2.3. Confirm account

Under normal circumstances end users would receive the confirmation link in an email and clicking on the link would initiate the following request.

curl -D- -XPUT http://localhost:5000/users/620366184447377/77fc990b-210c-4132-ac93-ec50522ba06f
HTTP/1.1 200

2.4. Second login attempt

curl -D- -XPOST http://localhost:5000/auth/login -d '{ "username":"test5", "password": "test" }'
HTTP/1.1 200
X-Set-Authorization-Bearer: eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiI2MjA1OTkwNjIwMTQ4ODEiLCJzdWIiOiI2MjAzNjYxODQ0NDczNzciLCJleHAiOjE0OTcxMDQ3OTAsImlhdCI6MTQ5NzAxODM5MCwiYXV0aG9yaXRpZXMiOiIifQ.U-GfabsdYidg-Y9eSp2lyyh7DxxaI-zaTOZISlCf3RjKQUTmu0-vm6DH80xYWE69SmoGgm07qiYM32JBd9d5oQ

After the user’s email address was confirmed it can now log in.

3. What’s next?

As I previously mentioned, there’s fair amount of work to do on this app. Among others it still lacks some basic features and it doesn’t have a UI either. You can following it’s progress here: https://github.com/springuni/springuni-particles/projects/1