Our fictive application — Backend (authorization and tokens)

Rasmus Eriksson
6 min readJul 2, 2019

Read https://medium.com/p/e17b2df29bf2 to get some context. Code for this article can be found in the authorization branch at https://github.com/MrMjauh/backend.timetracker.

Actual value

We have configured everything, the grunt work is done and we can finally spend some time working on the actual functionality.

You are not the domain expert, but before start building APIs you should get yourself a solid understanding/mental model of the domain. Do some drafts of different entities and contexts in the domain, go through it with others in your team, reiterate and then start implementing the APIs.

We want the users of our system to have an email and an identifier to google ID. A user will have multiple projects that it can do CRUD operations on. We need authorization and user context aware requests (cookie, token what ever) to handle those questions. So adding some real value will have to wait while we implement authorization.

Go with the flow

So basically JWT is the long lasting hype, small tokens that you don’t have to validate (table lookup), but instead pay a small price in computation for validating them. But once you start implementing JWT based systems you always get to these edges cases that are not fun:

  • What happens if the user want to reset the password?
  • What if I need to blacklist a leaked token?
  • How long should they be valid?
  • How should I provide new tokens?

Depending on your risk and security profile, you are going to have a sad time. JWT has a lot of wonderful properties though — that really suite a use case where you have a fleet of services. But for now we put a lid on JWT, lets go with good old session tokens. Invalidating them = deleting them from a lookup table.

The token flow

Very simple flow:

  • Google OAuth2 login, validate all is ok (this is another article)
  • Return a session token to our mobile application (this is another article)
  • Application uses that token to do API calls, stored in the db means we get access to the user’s information (this article)

We will limit ourselves to one token per user — meaning if this application grows, we will need to add session handling for more then once device. But for now we don’t care. We will only focus on the authorization part and leave token generation and login flow for another article.

Think

You have come this far, thought about what to use and why. You have restrained yourself from being one of those people that just slap a library/framework on it and call it a day. So we are going to think a bit more about it, it might be obvious but lets go.

We will be using tokens since cookies are very browser centric way of handling things. How should they be transported? Well, lets use the header, something like X-AUTH-TOKEN header. Historically speaking, the X- has been used to specify custom headers where X stand for eXtension or eXtra. Some firewalls oblige to this notation or custom headers, while other firewalls just strip away everything that is not a supported header. Also with https://tools.ietf.org/html/rfc6648, the IETF wants to deprecate the X- notation (since 2012).

How will we handle the client flow? Basically we will add our own filter, that will look for the X-AUTH-TOKEN header, add the corresponding security principal and roles found for that token.

Work work work

We start off by defining some persistence classes.

Persistence classes

Since we have a BsonID the created date is already embedded into the id. No need to create it again. We note that we only store one (!) session token, meaning, only one application can be active at a time. If the requirements change, we can, with some effort make it more durable. Each time a user visit one of our endpoints, we will do a db lookup and check that the token is valid.

When adding these it is important to think about the structure of Spring and its request lifecycle to know where it should be appropriate to inject the token lookup.

For us the filter (bright yellow block) is a good injection point. If you want dig deeper into filters, go ahead, but the gist of it: the filter block is a list of stacked filters that are ordered. Each filter processes the request/response and then sends it to the next. It is chain of responsibility, but where everyone gets to do processing, in order.

There is a filter type called OncePerRequestFilter which is kind of self explanatory.

Here it is important to note that I inject and create this filter in the configure method in Config.java. There are other routes to go, like @Component and @Order(n) where you make Spring boot generate, recognize and inject the filters.

Basically we read the X-AUTH-TOKEN and if there is a token inside it, we extract it and hit the database to check for an user. If an user is returned, we inject that user into the current SecurityContext that is bound to a request. By doing so, we can annotate controllers and methods with specific role based security. Using either jsr250 API or springs own. I personally like the Spring syntax more, using the @PreAuthorize annotations and they always seem to play more nicely with Spring. If you are thinking about abandoning Spring for the REST part, using the standardize syntax might be the better route to go.

We also add some convenient wrapper annotations (correct wording would be meta annotations), taking the abstract @PreAuthorize annotations and creating something more bound to our logic and domain.

You should really check out the config/auth package. This is only a start, but with some things added to it, you could create a common package that could be used by all your micro services. That means a lot of the boilerplating and trying to make your microservice ‘fit in’ will be abstracted away and you are mostly left with implementing the functionality.

We create a small controller to test out everything

But that is ugly, we don’t want to manually test our stuff. It is fine for prototyping I guess 🤔, but we should write a integration test for it. By the way, if you have not checked out the repository, we have written a couple of unit tests, if you want to check them out.

We want integrations tests to run separately from our unit test to not increase the feed back loop too much (time since you press run tests and until you see results). You need some gradle know how for this, I’ll not bore you with the details, check the repository if you want to know more (build.gradle).

Our project will now have a main, test and integration-test folder in src. One of the cool things with using mature libraries and frameworks like Spring is the ecosystem that surrounds it. At first you might cry (out of joy!) for all the different tools and libraries that are out there to make your life as a developer easier. Also I would highly recommend checking out the source code for some of these projects, you learn a lot from the very best that work in these projects!

Running integration tests is a blast and here our tactic will be to run test slices, that is, we decide some logical cut off where we mock after that point. As seen below in the code, our cutoff is in the service layer, so we test the TokenAuthenticationFilter and the UserController.

We have 2 test, one for testing BadRequest filter method and one for actually returning the correct value. We autowire in the mapper, so we don’t have to hardcode strings and instead rely on the internal mapper configuration. We use @Mockbean to automatically replace beans in the running context with a mocked version. The functions we need, we will mock! Make sure to clear the mocked services between runs.

So, that’s it! We can finally start doing things. In the next chapter we will dive into the actual domain logic and structuring, you can read more about it here TODO_LINK.

--

--