Monday, September 15, 2014

Secure your AngularJS Apps with Spring Security and Spring Session

A few days ago I was in the middle of preparing for my Spring One 2GX 2014 talk Creating Modular Test-Driven SPAs (Slideshare) with Spring and AngularJS. Part of the presentation is a demo application I created called botanic-ng. This application uses AngularJS on the client side and Spring (Boot) on the server-side. As I wanted to not merely create a simplistic toy app, I also intended to add authentication and (simple) authorization to the application.

I did not want to go too crazy with this (e.g. implementing full-fledged OAuth 2.0 integration). Nevertheless, I wanted to add (I hope) some meaningful security features inside my AngularJS application.

Disclaimer: I am not a security expert. Proceed with caution as this solution may not provide enough security for your application needs.

By chance I came across a demo application that Josh Long created a while back. That application, while using Spring Security, did not integrate with Spring Security to the fullest extends, and I felt that I could improve upon that implementation using Spring Session which is new project created by Spring Security lead Rob Winch.

Spring Session

The Servlet 3.0 Specification (JSR 315) introduced several ways to customize the handling of session cookies, for instance changing the name of the cookie (from the default JSESSIONID) and providing additional security relevant settings:

However, you're still pretty much bound to using cookies in order to store your Session IDs. For cases where you need more comprehensive flexibility for handling your sessions, Spring Session comes in quite handy and provides numerous advantages.

By default Spring Session stores session information in Redis using the RedisOperationsSessionRepository. Sessions expire by default after 30 minutes but this can be customized using the setDefaultMaxInactiveInterval property. Beyond Redis a MapSessionRepository is also provided to allow for easy integration with e.g. Hazelcast.

For my use-case, I wanted to expose the Session ID not via a standard cookies but via an HTTP header. Luckily, Spring Session provides various pluggable strategies to customize that behavior. As Spring Session works as a Filter you have to configure a SessionRepositoryFilter. On this filter you can set the used HttpSessionStrategy. By default it uses the CookieHttpSessionStrategy. For my use-case, though, I am using the HeaderHttpSessionStrategy, which by default stores the Session ID in an HTTP header called x-auth-token (This is customizable though).

On the client-side in my AngularJS application, I am adding a HTTP header via $http to every request.

$http.defaults.headers.common['x-auth-token'] = user.token;

This is configured upon successful login through the LoginControllerBotanic-ng submits the login credentials to the server, which in turn uses them to authenticate the user using Spring Security (AuthenticationController) and if successful, the AuthenticationToken containing the Session ID and user roles will be send back to the client.

The Session ID on the client is stored in memory only and if you refresh the client, the user must re-authenticate.

For the full source code, please see: 

Saturday, September 13, 2014

Spring One 2GX 2014 - My session slides

Have not blogged in a while. Need to make a mental note to revive that. Just came back from Spring One 2GX 2014 in Dallas, TX. It's been a wonderful event and I learned a lot - From microservices to reactive streams. I also gave 2 presentations which I think were well received. For my AngularJS with Spring (Boot) talk I had 140 attendees, yeah :-)

Creating Modular Test-Driven SPAs with Spring and AngularJS

Spring Batch Performance Tuning