SPRINGBOOT REST/JSON API + Header authentication + Swagger UI

Hello!

As told in previous post, today I will start an example (I hope to continue it with more features in the future) about creating a basic REST/JSON API, protected by authentication headers via interceptors, and documented automatically with Swagger. For that, I will use SpringBoot, instead of pure JAX-RS as used in other posts. First of all, say that at first I’m not very comfortable with any framework in general (as they hide how they work the most of the time, include lot of general but for-the-case unnecessary features, makes some times a big lost of performance, and because some times to learn that framework it’s more time costing & hard than developing a custom solution by yourself) but I must say that Spring is gaining me about: it’s easy, not so difficult to understand, and really saves you time. Anyway, I could use for this example as well Spring Security, but I prefer not, so we can check a little about interceptors and hashing.

As all source code is hanged on github in this post, I will just comment each part.

Ok, so as first, we start a maven project with some dependencies:

pom.xml

We will add general springboot package: org.springframework.boot/spring-boot-starter-parent

As is possible that in the future we use Netflix Eureka, and as well there will be some dependencies included in this package, we add org.springframework.cloud/spring-cloud-starter-eureka.

We add as well the spring maven plugin with org.springframework.boot/spring-boot-maven-plugin

For logging system, we will use log4j implementation over the standard Spring logging, so we will add log4j/log4j and org.springframework.boot/spring-boot-starter-logging

As Spring packages got so many variations, but final packages are in fact aproximatelly the same, it is very possible that inner jars are duplicated in some of these starter packages. Surely finer configuration it’s possible.

For swagger integration we will add io.springfox/springfox-swagger-ui and io.springfox/springfox-swagger2.

Finally, for utility functions we add org.apache.commons.codec.

Let’s go for the code.

Application.java
Springboot applications got embedded an Apache Tomcat that adds server features. Generating an application is just then to create a main class with the Spring annotation @SpringBootApplication, to denote entry point to Spring, and @Configuration annotation to make it execute one unique time at first. Then, inside the main class, just run SpringApplication using our class as argument.

With just this class (less than 10 lines of code), if we run that compiled jar file, we will see a working Apache server listening on 8080. Of course, it will not do anything really, except managing 404 errors, but anyway, we had left away a very big bunch of work (Apache/Glassfish configuration, domains creation, etc…)

At this point, in normal Java code we should initialize all needed classes (i.e., database connection, loggers, remote server connectors, etc…) but with Spring, using the @Configuration annotation should execute that class at first, and using @Autowired we can use singleton created objects in that configuration marked classes, when needed. In other words: @Configuration annotation allow us, again, to leave away another big time-consuming tasks…

PingController.java
For each service we want our API to supply, we should write a controller. To make a class controller it’s very similar that with JAX-RS: just using each needed annotation @RestController & @RequestMapping (path) to indicate that will be published and where, and how, and then annotate as well our methods. In this case in special I’m passing HttpServletRequest as a request param, so full request will be mapped by Spring to function param, and then I use it for a unique identification on log for each request. Anyway, it is not really in need to add HttpServletRequest request params.
As putting on annotation @RequestMapping on methods the ‘produces’ value to application/json, Spring will automatically return that kind of response, so, no need to manually deserialize to JSON.

And right now, if you execute your code, you will get a full REST/API working on localhost:8080 (!)

Anyway, let’s add some features…

UidInterceptor.java
This interceptor will pick up request just before being processed (at preHandle). Here we put a custom random positive long value on request attributes. This value, then, will be accessible for all classes that access to this request object. We will use it to identify each request on log.

ValidationInterceptor.java
With this interceptor we will check out headers U (user), ST (Salt), SH (Salted hash) and as well header X-Real-Ip. If a method is marked to use these headers, then in interceptor’s preHandle we will check if they exist and do verification of salt and salted hash (calculated with password associated with user and with salt itself). This way, any request will get just a lifetime (associated with its salt, that should be Unix timestamp) and so salted hash will make it full hidden from man-in-the-middle attack. About development, just using this interceptor makes us forgetting about anything else about authentication. Client developer as well got benefits just adding that headers for each request, and not depending on body or url params.

About X-Real-Ip header, this will be filled in by reverse proxy nginx, retrieving original source Ip from TCP packages on request, recursively. This way we will store on log the real Ip from which each request comes. We could do some verification here (IP whitelist) but there’s no need to in this example.

As told before, this authentication method is included in Spring Security, just using annotations. Anyway, I think that Spring Security is more focused to be integrated with a full MVC web application (cookies, sessions, etc…) than just securing api requests. In my work experience, I’d found that is easier and more efficient to make an authentication of each API call instead of first get a token, keep it, verify its life, relogin if sessions goes out, etc… Just as told: spring security seems more focused on full MVC web app.

InterceptorConfig.java
We add our two interceptors using another @Configuration class, making one instance of each using @Autowired annotation. Note that we don’t mind about autowired object creation, neither maintenance nor scope visibility: just declaring & mark them we are sure we will get a unique object alive of that class during all application life.

And that’s all at API level! We got now a secured API. It’s true that it just makes ping or ping with echo, but making new controllers are really easy, and the most important: you don’t mind about anything general or full API compromising. Now, with this structure, passing project to another developers, or more over, to ask to a team to create needed controllers, makes no worry about new inserted code: any general API part need to be touched for anything.

Ok, let’s now integrate Swagger. Swagger generates a webpage that will document our API automatically: we just need to mark some description params and then tell Swagger which controllers to document.

SwaggerConfig.java
We will use this @Configuration class to define our Swagger. We use for that the annotation @EnableSwagger2 to tell swagger our general description, and which packages to document. Note that in our example we mark as host my dns server name, vps355126.ovh.net, and which pathMapping to use. That is because on production nginx will reverse proxy all calls from vps355126.ovh.net:8081 to 127.0.0.1:9001, that is where springboot app listens. This way swagger can show & make the sample calls properly. PathMapping allows you to adjust path between what see swagger user and were call will be really sent.

nginx configuration

Just for finish, I had put in my nginx conf mapping as this, to allow search for original IP recursively, fill with it X-Real-IP header, and proxy pass to locahost 9001, where springboot app it’s running. Note it maps from /restexample/, so as told, swagger config should take care of this as well.

server {
    listen       80;
    server_name  vps355126;

    set_real_ip_from 10.0.0.0/8;
    real_ip_header X-Real-IP;
    real_ip_recursive on;

    #springboot
    location /restexample/ {

	set $http_x_real_ip $remote_addr;

        proxy_set_header X-Real-IP $http_x_real_ip;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:9001/;
    }
}

And that’s all! We got a full autodocumented and authenticated REST/API, with the stability & scalability of Java/Spring behind. You got the raw ping here, the authenticated one just adding an echo at url, and Swagger autodocumentation here

NOTE: due normalization update on 2017/12/29, now API & Swagger can be reached at http://vps355126.ovh.net:8081/ping & http://vps355126.ovh.net:8081/swagger-ui.html. So, path adjustements with /restexample/ path part are no needed any more, neither in SwaggerConfig, neither in nginx/conf.d/default.conf.

 

Hope you find it useful!

Best,

 

Advertisements

One thought on “SPRINGBOOT REST/JSON API + Header authentication + Swagger UI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s