Microservice authentication and authorisation

Below is a sequence diagram describing a common pattern for handling authentication and authorisation in a microservice solution, where you have a number of small web services interconnected and don’t want them all having to implement  authentication and authorisation individually, just to be simple services focused on their job.

Microservice authentication and authorisation seq

Using this pattern you can have any number of business microservices, all using the authentication automatically and calling the same authorisation service when necessary, making them simpler to implement and re-using the services easier.

You can go a step further and put the authorisation checks in the reverse proxy against each service endpoint but this requires the reverse proxy to know the actions/permissions of each service, plus it’s likely your services permissions will be dynamic based on execution.

Nginx with lua scripts are a good way of implementing the smart reverse proxy, below are some links about this.

 

 

 

Dropwizard Handle Exceptions

I’ve made a sample application showing how to create an exception provider which catches exceptions thrown inside resources and handles them gracefully in your application.

This example uses a Jetty Provider ExceptionMapper (RuntimeExceptionMapper.java) to handle any RuntimeExceptions thrown inside the application, which logs the exception and returns an appropriate response.

package com.example.providers;

...
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
...

@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {

    @Override
    public Response toResponse(RuntimeException exception) {

        Response response500 = Response
                .serverError()
                .entity(new ErrorView(exception, "500.ftl"))
                .build();

        ...

        return response500;
    }
}

The provider should be added to the environment in the Run method of the Service class.

package com.example;

...

public class ExampleService extends com.yammer.dropwizard.Service<ExampleConfiguration> {

    public static void main(String[] args) throws Exception
    {
        new com.example.ExampleService().run(args);
    }

    @Override
    public void initialize(Bootstrap bootstrap) {
        bootstrap.setName("dropwizard-handle-exceptions");
        bootstrap.addBundle(new ViewBundle());
    }

    @Override
    public void run(ExampleConfiguration configuration, Environment environment) throws Exception {
        environment.addResource(new UserResource());

        environment.addProvider(new RuntimeExceptionMapper());
    }
}

Got the idea from here.