Over a million developers have joined DZone.

Secure your AngularJS Apps with Spring Security and Spring Session

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

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 theRedisOperationsSessionRepository. Sessions expire by default after 30 minutes but this can be customized using the setDefaultMaxInactiveInterval property. Beyond Redis aMapSessionRepository 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 theCookieHttpSessionStrategy. For my use-case, though, I am using theHeaderHttpSessionStrategy, 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: 

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

java ,enterprise-integration ,security ,spring ,tips and tricks ,angularjs

Published at DZone with permission of Gunnar Hillert. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}