Securing Microservices with Auth0 Pt. 2 (Resource Service)
Tags: react, spring, microservices, tutorial
Published: 2019-09-25 21:59:36

This is the second part to a series of posts called **Securing Microservices with Auth0**. If you missed the [previous post](https://dev.to/bbenefield89/securing-your-microservices-with-auth0-20e3), I would suggest you go back and read that post first.


# Overview

In this part of the **Securing Microservices with Auth0** series, we're going to be creating the **Resource Service** microservice. The **Resource Service** will be our applications **REST API** and will perform **CRUD** operations on specific users **Todos**. By this I mean we will be able to:

- **C**: Create (POST)
- **R**: Read (GET)
- **U**: Update (PATCH)
- **D**: Delete (DELETE)

At first, this service will be insecure and will not need any sort of authentication. It's important that we see the issues that come with insecure applications both from the developer perspective and the user perspective. After creating our **Auth Service**, which will be a different **microservice** in another post in this series, we will then perform **authorization** on requests being sent to our **Resource Service**.

You can also go ahead and play around with [the code](https://github.com/bbenefield89/SpringTodo/tree/bbenefield89/tutorial_pt2) for this post. This branch, `bbenefield89/tutorial_pt2`, is the UI portion and the insecure RESTful API (**Resource Service**).


# Creating the Resource Service

For this series, I've decided to go with the [Spring Framework](https://spring.io/) to create our backend. **Microservices** are **not** **Java/Spring Framework** specific and we can just as easily create our **microservices** in any language that has the ability to create a web server and make HTTP requests. This means we could potentially create our **Resource Service** using [Express the Node Web Framework](https://expressjs.com/) and then turn around and create our **Auth Service** using [Django the Python Web Framework](https://www.djangoproject.com/). This is one of many of the advantages of going with a **microservice architecture** when creating your applications.

Enough talk, it's time for action! Let's head over to [Spring Initializr](https://start.spring.io) where you can quickly create the boilerplate code for your **Spring** application.

When you land on the **Spring Initializr** page go ahead and enter in the basic information for your project. As an example, my projects information will look like this:

<img src="https://thepracticaldev.s3.amazonaws.com/i/vb2qa20lubwgjts0s6b9.PNG" width="100%">

And my chosen dependencies will be:

<img src="https://thepracticaldev.s3.amazonaws.com/i/x2cbg1tvyffv7907m4r7.PNG" width="100%">

Go ahead and click on the green button at the bottom that says `Generate the project`. This will prompt you to download your project as a **zip** folder.

<img src="https://thepracticaldev.s3.amazonaws.com/i/eth1pxnsg9b233njwjpw.PNG" width="100%">

Unzip your project, feel free to discard the **zipped** folder, and let's open up our project in our favorite IDE and get to work.


# Inside our Resource Service

Now that we're ready to go, let's find our first file at `TodoApp_API/src/main/resources/application.properties` and rename that to `application.yml` as I'm a fan of `YAML` when it comes to **Springs** configuration properties.

Inside our `application.yml` file you'll notice it's empty. Go ahead and place the following text inside:

```yml
server:
  port: 8080
```

It's not much, and to be honest **Spring** defaults it's **PORT** to **8080** but I like to be as clear as possible, especially when we have multiple services for the same application.


## Creating the `Todo` **Entity**

We've already discussed the application and yes, this is going to be yet *another* todo app but I believe creating something you're familiar with is best when learning about new technology. Might as well focus on the technology instead of the logic.

Create a new **package** at `TodoApp_API/src/main/java/${}/${}/TodoApp_API` and name it **Entities** (`TodoApp_API/src/main/java/${}/${}/TodoApp_API/Entities`). This package is where we're going to create all of our **Entities** which are basically just a **Java** representation of a row in our DB.

Inside the **Entities** folder, create a new **Java** file and name it `Todo.java` and inside of it place the following code (filling in the ${} with your own path). Be sure to read the comments as I'll explain some of the code as we go.

**Todo.java**
```java
package ${}.${}.TodoApp_API.Entities;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * This annotation comes from "Lombok" and allows us to forget about writing
 * a lot of boilerplate code like "Constructors/Getters/Setter"
 */
@Data
// Creates this class as a Bean to be picked up by Spring
@Entity
public class Todo {

    // Lets JPA know this is the unique identifier for our DB
    @Id
    // Sets the value that should be automatically generated for our ID in the DB
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    // We'll use the users' email address to find a user's todos
    private String userEmailAddress;

    /**
     * Notice we don't have to write anything else
     * Lombok will take care of this for us
     */

}

```

## Creating the `TodoRepository` "Repository"

The **Repository** for an **Entity** is going to be an interface that will extend another interface that comes with a ton of helpful methods to perform all of our **CRUD** operations.

Create another package named `TodoRepositories` and place it at `TodoApp_API/src/main/java/${}/${}/TodoApp_API/Repositories`. Inside create a new file named `TodoRepository.java` and inside place the following code:

**TodoRepository.java**
```java
package ${}.${}.TodoApp_API.Repositories;

import ${}.${}.TodoApp_API.Entities.Todo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Sets this interface up to be found by Spring
 * Later on we'll be taking advantage of the @Autowired annotation where this interface will then become a
 * concrete class
 */
@Repository
/**
 * Our repository interface needs to extend the JpaRepository interface and pass along two arguments
 * 1. The Entity class that this repository is responsible for
 * 2. The id data type we chose for the Entity this Repository is responsble for
 * In this example, we've chosen to create our id as a Long data type
 */
public interface TodoRepository extends JpaRepository<Todo, Long> {

    /**
     * This is a custom method we'll be using to get a list of todos depending on the users email address
     * JPA supports a type of DSL where we can create methods that relate to an Entity by using keywords
     * 1. "findAll": returns a List of Todo
     * 2. "By": This signifies that we are going to be giving something specific to look for in the DB
     * 3. "UserEmailAddress": Find a Todo that contains the correct "userEmailAddress" in the DB
     */
    public List<Todo> findAllByUserEmailAddress(String userEmailAddress);

    /**
     * Another custom method. This method will take the ID of a Todo and the users email address to return a
     * single Todo
     */
    public Todo findByIdAndUserEmailAddress(Long todoId, String userEmailAddress);

    /**
     * This custom method will delete a single Todo depending on the ID and the userEmailAddress
     */
    public void deleteByIdAndUserEmailAddress(Long todoId, String userEmailAddress);

}


```

That's it for our **Repository**. We've only added a few methods but **JpaRepository** will still give us access to a lot more of the inner methods that we haven't defined.


## Creating the `TodoService` "Service"

The idea behind a **Service** in this context is to bridge the gap between a **Controller** and a **Repository**. This is also where you will write your business logic. Splitting up your code like this keeps things small and typically easier to reason about.

Go ahead and create another package named `Services` and place it at `TodoApp_API/src/main/java/${}/${}/TodoApp_API/Services`. Inside, create a file named `TodoService.java`.

**TodoService.java**
```java
package ${}.${}.TodoApp_API.Services;

import ${}.${}.TodoApp_API.Entities.Todo;
import ${}.${}.TodoApp_API.Repositories.TodoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Lets Spring know to pick this up at runtime
 * You've probably noticed that so far we haven't really told Spring when to use any of our classes and that's
 * because of "Component Scanning". To learn more about the Component Scanning go to the following URL
 * https://www.baeldung.com/spring-component-scanning
 */
@Service
public class TodoService {

    TodoRepository todoRepository;

    /**
     * @Autowired annotation sets this constructor to be called when booting our application and will automagically
     * inject any dependencies that we specify in the arguments
     * This is also known as "Dependency Injection" and is one of the more attractive aspects of the Spring Framework
     */
    @Autowired
    public TodoService(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }

    // Returns a List of all of a users Todos
    public List<Todo> findAllByUserEmailAddress(String userEmailAddress) {
        return todoRepository.findAllByUserEmailAddress(userEmailAddress);
    }

    // Return a single Todo
    public Todo findByIdAndUserEmailAddress(Long todoId, String userEmailAddress) {
        return todoRepository.findByIdAndUserEmailAddress(todoId, userEmailAddress);
    }

    // Create/Update a new Todo and returns that Todo
    public Todo save(String userEmailAddress, Todo todo) {
        todo.setUserEmailAddress(userEmailAddress);
        return todoRepository.save(todo);
    }

    // Delete a Todo
    public void deleteByIdAndUserEmailAddress(Long todoId, String userEmailAddress) {
        todoRepository.deleteByIdAndUserEmailAddress(todoId, userEmailAddress);
    }

}
```

## Creating the `TodoController` "Rest Controller"

Okay, we're almost finished with our first pass on our **Resource Service**. We just need to create the **Controller** that will determine our **services'** URL endpoints.

Create your final package named `Controllers` and place it at `TodoApp_API/src/main/java/${}/${}/TodoApp_API/Controllers`. Inside, create yet another file and name it `TodoController.java` and place the following code inside.

**TodoController.java**
```java
package io.github.bbenefield89.TodoApp_API.Controllers;

import io.github.bbenefield89.TodoApp_API.Entities.Todo;
import io.github.bbenefield89.TodoApp_API.Services.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/todos")
public class TodoController {

    private TodoService todoService;

    @Autowired
    public TodoController(TodoService todoService) {
        this.todoService = todoService;
    }

    // Returns a List of Todos
    @GetMapping("/{userEmailAddress}")
    public List<Todo> findAllByUserEmailAddress(@PathVariable String userEmailAddress) {
        return todoService.findAllByUserEmailAddress(userEmailAddress);
    }

    // Returns a single Todo
    @GetMapping("/{userEmailAddress}/{todoId}")
    public Todo findByIdAndUserEmailAddress(@PathVariable String userEmailAddress, @PathVariable Long todoId) {
        return todoService.findByIdAndUserEmailAddress(todoId, userEmailAddress);
    }

    // Creates a new Todo
    @PostMapping("/{userEmailAddress}")
    public Todo save(@PathVariable String userEmailAddress, @RequestBody Todo todo) {
        return todoService.save(userEmailAddress, todo);
    }

    // Deletes a single Todo
    @DeleteMapping("/{userEmailAddress}/{todoId}")
    public void deleteByIdAndUserEmailAddress(@PathVariable String userEmailAddress, @PathVariable Long todoId) {
        todoService.deleteByIdAndUserEmailAddress(todoId, userEmailAddress);
    }

}
```


# Manually testing our endpoints

Now that we've written our endpoints it's time we test them to make sure everything works. I would suggest downloading [Postman](https://www.getpostman.com/downloads/) for API testing.

Let's go ahead and start making some HTTP requests.

### POST `localhost:8080/api/todos/user@gmail.com` (Create Todo)

**Example Request**

```json
{
    "title": "Get a haircut",
    "userEmailAddress": "user@gmail.com"
}
```

**Example Response**

```json
{
    "id": 1,
    "title": "Get a haircut",
    "userEmailAddress": "user@gmail.com"
}
```

<img src="https://thepracticaldev.s3.amazonaws.com/i/yf6ef9m05zuefzbvaq5h.PNG" width="100%" />


### GET `localhost:8080/api/todos/user@gmail.com` (Get All Todos)

**Example Request**
```
Nothing required
```

**Example Response**

```json
[
    {
        "id": 1,
        "title": "Get a haircut",
        "userEmailAddress": "user@gmail.com"
    }
]
```

<img src="https://thepracticaldev.s3.amazonaws.com/i/tmp5rkjznq5zvageph6s.PNG" width="100%" />


### GET `localhost:8080/api/todos/user@gmail.com/1` (Get a Single Todo)

**Example Request**
```
Nothing required
```

**Example Response**

```json
{
    "id": 1,
    "title": "Get a haircut",
    "userEmailAddress": "user@gmail.com"
}
```

<img src="https://thepracticaldev.s3.amazonaws.com/i/tqz4o49c2z6mcxpdcl81.PNG" width="100%" />


### DELETE `localhost:8080/api/todos/user@gmail.com/1` (DELETE a Single Todo)

**Example Request**
```
Nothing required
```

**Example Response**

```
Nothing returned
```

<img src="https://thepracticaldev.s3.amazonaws.com/i/4ky5mdktnswi3ce0pj3z.PNG" width="100%" />

Great, everything works! The only problem now is that our endpoints aren't secured (to be fair we don't *really* have any users either). This means, you as the user `hacker_man@gmail.com` could easily access my data and vice versa.


# Conclusion

In this post, you didn't learn much about **Spring** or **Auth0** but you did learn about creating RESTful endpoints which is an important step to the process. Not to mention, you now see how easy it is for insecure endpoints to be accessed by the wrong people.

In the next section of this series (link coming soon), you'll get an introduction on how to create a very simple **Auth Service** that uses:

- **Spring Security**: Prevent access to users that are not authed

- **Prehandle**: A method to intercept requests to endpoints that we can use to run logic before all requests (the secret sauce of our **auth**)