Securing Microservices with Auth0 Pt. 4 (Bring it all together)
Tags: react, spring, microservices, tutorial
Published: 2019-10-03 21:59:14

This is the third part to a series of posts called Securing Microservices with Auth0. If you missed the [previous post](https://dev.to/bbenefield89/securing-microservices-with-auth0-pt-3-42nb), 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 finally secure our **Resource Service** by requiring that all requests to an endpoint must first go through our **Auth Service**. If you remember from the previous post, if the request fails due to an invalid `access_token` then the request stops there. If the request goes through and sends over a valid `User` we can then make a query to our DB to perform CRUD operations on behalf of a user.

Just to clarify the **Auth Flow**, let's take another look at the diagram from the [previous post](https://dev.to/bbenefield89/securing-microservices-with-auth0-pt-3-42nb).

<img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vafOOsSA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/d06jb0z7q5j9ub0weewi.PNG" width="100%" />

- Make request from client side (or Postman), passing up our `access_token`

- **Resource Service** make request to **Auth Service**

- **Auth Service** sends `access_token` to **Auth0**

- **Auth Service** sends a `User` object back to **Resource Service**

- **Resource Service** performs CRUD operation

- Return data back to the client


# Back to the **Resource Service**

### Create `RestInterceptorAll` Interceptor

Back in our **Resource Service**, we need to create another `Interceptor`. This `Interceptor` is going to be very similar to the `Interceptor` from our **Auth Service** and the idea is pretty much the same. Go ahead and create a new package in your **Resource Service**, `Interceptors`, and create a new class, `RestInterceptorAll.java`.

**RestInterceptorAll.java**

```java
package ${}.${}.TodoApp_API.Interceptors;

import ${}.${}.TodoApp_API.Models.User;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class RestInterceptorAll extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        try {
            HttpHeaders headers = setAuthorizationHeader(req);
            HttpEntity<String> entity = new HttpEntity<>("headers", headers);
            User user = getUserInfoFromAuthService(entity);
            req.getSession().setAttribute("user", user);
            return super.preHandle(req, res, handler);
        } catch (Exception e) {
            // Users "access_token" is wrong so we should notify them that they're unauthorized (401)
            res.setStatus(401, "401 Unauthorized");
            // Return "false" so the "ValidateController" method isn't called
            return false;
        }
    }

    // Sets the "Authorization" header value (Authorization: Bearer ${access_token})
    private HttpHeaders setAuthorizationHeader(HttpServletRequest req) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", req.getHeader("Authorization"));
        return headers;
    }

    // Sends a GET request grab the users info
    private User getUserInfoFromAuthService(HttpEntity<String> entity) {
        RestTemplate httpRequest = new RestTemplate();
        return httpRequest.exchange(
                "http://localhost:8081/api/validate",
                HttpMethod.GET,
                entity,
                User.class
        ).getBody();
    }

}
```

I'm sure you'll notice that it's extremely similar to our **Auth Service**, and like I said, the idea is pretty much the same.

- Intercept requests to an endpoint

- Make HTTP request to our **Auth Service**

- **Auth Service** will then validate the `access_token`


### Create `MvcConfig` Config

Again, similar to our **Auth Service**, we need to register our `Interceptor`. Create a new package, `Configs`, and inside create a new file, `MvcConfig.java`

**MvcConfig.java**

```java
package ${}.${}.TodoApp_API.Configs;

import ${}.${}.TodoApp_API.Interceptors.RestInterceptorAll;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    private RestInterceptorAll restInterceptorAll;

    @Autowired
    public MvcConfig(RestInterceptorAll restInterceptorAll) {
        this.restInterceptorAll = restInterceptorAll;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Registers our "RestInterceptorAll" into the list of global interceptors
        registry.addInterceptor(restInterceptorAll);
    }

}
```


### Revisiting the `TodoController` Controller

Now that we've registered our `Interceptor`, we need to alter our **Controller** for some additional security. At this point, a user could easily send up an `access_token` that is for `user1@gmail.com` but they could send this from the `/api/todos/user2@gmail.com`. We need to make sure that not only is the `access_token` valid, but that we're grabbing data for the correct user.

To save space, I'm only going to show a portion of the `TodoController`. I'd really like to encourage you to use the same pattern in this `@GetMapping` method and try to secure the rest of your methods. If you have trouble, don't worry, I'll provide the [updated code in the controller](https://github.com/bbenefield89/SpringTodo/blob/bbenefield89/tutorial_pt4/TodoApp_API/src/main/java/io/github/bbenefield89/TodoApp_API/Controllers/TodoController.java).

**TodoController.java**

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

    private TodoService todoService;

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

    /**
     * Returns a List of Todos
     * Here we are adjusting the parameters for our "GetAll" method
     * We want to grab the User object being passed around the current session
     * and compare the users email address from the User object with the
     * path variable for the current URL
     * If something doesn't match we're going to tell the user that they're
     * 401 Unauthorized
     */
    @GetMapping("/{userEmailAddress}")
    public List<Todo> findAllByUserEmailAddress(
            @SessionAttribute User user,
            @PathVariable String userEmailAddress,
            HttpServletResponse res) {

        if (user.getEmail().equals(userEmailAddress)) {
            return todoService.findAllByUserEmailAddress(userEmailAddress);
        } else {
            todoService.unAuthorizedAccess(res);
            return null;
        }
    }

    ... the rest of the methods are down here ...
}
```


# Conclusion

Wow, you did it! You should have a pretty secure set of microservices ready to be extended into whatever amazing project you can think up.

I'm sure I'll get a few confusing looks about why we're not wiring up the frontend we create in part one. That's because this really wasn't meant to be a full-fledged tutorial on React and I really wanted to focus on the backend. Hopefully, if you made it this far, you learned something new and I encourage you to flesh out your frontend. If you do happen to finish this project, be sure to host it somewhere and share it in the comments below.

### What did we learn?

- The **Microservice Architecture**

- Securing a SPA with [Auth0](https://auth0.com)

- Spring Interceptors

- How to make HTTP requests using `RestTemplate` from Spring

- How to validate `access_tokens`