Securing your mobile API - Spring Security

Having recently posted an article on an approach to securing an API for a mobile app to use, here are the details of how something similar can be configured using Spring-MVC and Spring-Security (this post uses Java config - if you are un-familiar with Java config rather than XML then check out my previous post on the topic).


Basic webapp registration and authentication

The first thing we need is a basic web app that supports user registration and authentication.  I am not going to go into the details of how to build a Spring MVC app with basic security and users etc, so will assume you are familiar with basic Spring MVC architectures. For an example Spring webapp that supports user security and registration, you can check out one of my several random webprojects on GitHub.


As I am only looking at an API application - no web client right now - All I need to start with is to set up the security for registration and login:



Ok, so the above is my web security config - the configure() method is what is defining my URLs and the security - it's pretty basic, I state that anyone can access the resources (for css etc), the log-in and the sign-up and everything else should be authenticated.

The only parts of interest are:
  1. In the registerAuthentication() method, as well as the normal setting of UserServices and password encryptor, I am also adding a Remember Me Authentication provider
  2. In the configure() method on the formLogin component we are also setting a RemeberMeService
  3. We are setting @Order annotation on the class with value 2

This class basically just sets up the web part of the security, so all pretty straight forward.


API security configuration

For clarity and readability of code, I like to create separate configuration classes for the different aspects of security - Below is the security config for the API endpoints:



This file is a little more interesting, let's have a look at what is going on:
  1. First of all, we define @Order with value 1 - as you have probably guessed, this defines the order in which the security config is loaded/considered - we want the API security to kick in first
  2. In our configure() method, we first specify an ant matcher so the rules in this config only apply to URLs that start /api/
  3. We state that all requests to this pattern must be authenticated and apply a RememberMeAuthenticationFilter to run before the Basic authentication chain runs
  4. We also set the session management to be stateless - this refers to serverside sessions, as we don't want to retain server session state
  5. We then configure the Remember Me beans - this is all standard and as per the Spring guidelines here.  The only difference is that we have a custom TokenBasedRememberMeService - that we will look at later.


Security flow

Below is the basic security chain that we get as a result of the above confirmation
  1. Request comes in - we check if it matches /api/**
  2. If it does match, then all requests must be authenticated - and run the RememberMeAuthenticationFilter 
  3. The filter simply uses the RememberMeService and AuthenticationProvider to check the token/cookie value to see if it can pre-authenticate the request.
  4. If it has matched the URL but doesn't authenticate on the filter, then it will 403
  5. If the URL does not match /api/** then the request starts the second security config
  6. If the url matches the resources, sign-up, sign-in then allow the request to complete, otherwise require authentication, so (default spring behaviour) direct all other requests to the registered login page ("/")


Customising remember me

 So the good news is we have been able to re-use core Spring Security functionality so far, so no dubious hand-rolled solutions - We use the standard security chain, username/password authentication provider and Remember Me filter/provider. The only thing that we have to modify slightly is the RememberMeTokenService - the default behaviour for Remember Me assumes that the token will always be provided in a cookie (designed for auto-login websites if you tick "remember me"), and as we are extracting the token from the cookie and passing it in the request header instead, we need to modify the service class to grab it from the header.

As you can see, it's pretty simple - all we are doing is overriding the default extract cookie method so it looks in the request header instead.  I would really recommend you read through the source code for the RememberMe classes - starting with the filter - and seeing what is actually happening between the Filter, token service and auth provider, it's pretty clear to read and will help get a good understanding of what is going on.


Caveats

There are a few things to consider here:
  • This is fairly basic security - requests should be made over https to prevent man-in-the-middle attacks, alternatively look at a solution like Amazon use whereby the token isn't passed, rather it is used to hash the request body which is then checked on the server side (prevent the need for sending the user token every request)
  • This is currently open to anyone to use/build against - there aren't any checks for app key/secret etc - so you would probably want to build that in to prevent other parties building apps against the api and getting a user token in the same way.
  • I'm not a security expert - this is just my interpretation of the Google guidelines using Spring Securities RememberMe classes. This is really just a thought experiment, getting up to speed with how Spring Security works in more details and experimenting with mobile app fun. Use at your own risk..

31 comments:

Securing your API for mobile access

So I have been thinking about potential options regarding securing a server side API for use by mobile apps. No matter what question you ask on the stack exchange network, the answer will always come back as "you should really use oauth", which I guess we should consider as a half truth.

Having used OAuth on several occasions as a client (accessing Facebook/Twitter/LinkedIn/GitHub etc), it was naturally the first option that came to mind for securing my API.


My requirements right now are simple:
  • I am experimenting building an Android mobile app that will use a server API (webapp & API will be built using Java & Spring stack)
  • The app I am experimenting is mobile-only (no web client)
  • It is not going to become a public API (e.g. won't be supporting other apps/sites)


I guess the key point is that I only intend to expose the API to my mobile app, and not have lots of comsumers of the API - and given the complexity of implementing OAuth, it seemed like it would be overkill as a solution.  A big benefit of OAuth is that it supports client/application keys.


So I started looking around for other ideas as to how to do this - I was (and still am) curious as to how Twitter/Instagram secure their APIs for their own applications - I know that the Twitter API is secured for public use using OAuth, but the interesting question is how they secure their own application key/secret. The problem with mobile apps is that an application key needs to be stored on the device - and whilst Twitter offers severely throttled API access using OAuth (register an application, get a secret app key etc), their own apps are obviously not throttled, so it seems like it would be a challenge to keep their application key secured, as if its in the app code, then its subject to de-compilation.

Anyway, getting close to resigning to the fact that I was going to have to use OAuth I came across this one-pager from Google. The guide suggests a much simplified approach with the following basic steps:

  • Build an webapp on your server that has a login page 
  • From your mobile app, embed a WebView of the login page
  • Upon login to your app, return a cookie with a token value that can be used to log in your user on future requests - ideally re-using your frameworks Remember-Me type services so not to have to hand-roll your own
  • On every API request include the token in your request header to authenticate (again using the Remember Me services)

The fact that it was a suggested approach from Google is pretty good, and it's a tonne simpler than negotiating the OAuth dance, so I thought I would have a look at getting this setup.


This is all good - but really, the advice to use OAuth is a half-truth, as if you ever have to scale your application, and think you might one day have/want to open it up do other developers/clients then OAuth is the way to go - You won't get much love from third-party developers with a non-standard approach to securing your API.


So.. how can it be done with Spring? I will cover that in my next post later this/next week!

2 comments:

Everything is Technology

So, having pondered the merits and likely outcome of the UK government's Year of Code initiative, you could rightly be left to ponder, "who cares?". A lot of the UK's population may not consider themselves hugely tech savvy, and certainly not formally trained in tech, and we are getting by. The country has naturally produced enough nerds/tech folk to keep us as a respectable tech power in the modern world. Plus, kids these days are so emersed with tech/internet/mobiles they will be naturally equipped for the future world of work.

Maybe?


A little while ago, Marc Andreessen (of Silicon Valley Venture Capital firm Andreessen Horowitz) wrote an article titled "Why software is eating the world", referring to the pervasiveness of tech and how slowly, tech, and the internet, is disrupting more and more industries, changing the way they operate and where/how they compete for profit.

So the question is, will being "power users" on Facebook, CandyCrush, Twitter, etc be enough in the predicted software devoured world?

Some obvious examples of industries that are now tech industries spring to mind:
  • Amazon - completely changed the face of retail and is almost single handedly making high streets around the uk obsolete
  • iTunes et al - once again, changed the face of the music industry, record shops etc
  • AirBnB - changing the way that people think about travel and disrupting the hotel/holiday accommodation industry.


High profile and a very real, visible impact on the economy, and as Andreesen quotes in his article:
"Today, the world's largest bookseller, Amazon, is a software company—its core capability is its amazing software engine for selling virtually everything online, no retail stores necessary. On top of that, while Borders was thrashing in the throes of impending bankruptcy, Amazon rearranged its web site to promote its Kindle digital books over physical books for the first time. Now even the books themselves are software."

The important bit being "its core capability is its amazing software engine" - Amazon isn't a retail business, its a tech business - its core skills and expertise, and the majority of its employees are in tech.  The fact that it can branch out so easily into its Cloud services is testament to that. They have an amazing tech platform, with amazing tech folk, that is their business.

So that's an obvious example - we aren't all going to be working at Amazon/Google etc. But the thing is, its not just the obvious examples that are being disrupted. Let's look at an industry that is apparently yet to be disrupted: insurance. Any big online insurers coming in and turning things on their head the way amazon did retail? Nope. Look for any form of personal insurance in the UK and lots of familiar names still come up: The AA, Tesco, First Direct, Royal & Sun Alliance etc. Look a bit beneath the surface though, and you will realise the industry has really become a tech arms-race. Aggregator websites like money supermarket.com or comparethemarket.com have indirectly completely changed the industry with tech.

What was once a very personal industry, all about understanding people & risks and where an experienced actuary held the power, has become a race to the bottom in terms of latency and efficiency for quote generation.  The aggregator sites drive so much traffic to insurers (approximately 60% of all insurance quotes originate from these sites), and such high volumes (~10-11 million a month) that to stay in business, insurers have to have the tech to serve up quotes a) faster than others b) cheaper than others.

If your system costs a penny more to generate a quote than your competitor, at 11 million quotes a month, that's an extra £110,000 you need to generate every month (thats the cost just to generate the quotes - if you don't actually manage to convert any of those quotes, that's a pretty quick path to bankruptcy), which is most likely going to push up your premiums, which will in turn decrease your chance of conversion.

Honestly, with so many of these companies having to support monolithic legacy tech systems, I would be surprised if they didn't soon get replaced - all a start-up would need is financial backing to underwrite the claims, and a few decent tech folk to build a web friendly (web services, REST etc.) insurance system, built with aggregators in mind plus a slick web app to allow easy (and free) policy management, and they could probably undercut and offer better customer service than the all the big guns so severely that they would have no choice but retire.

EVERYONE, LEARN TO CODE. NOW!


No. Not really. 

Does everyone need to know how to code? Of course not. The point of introducing tech more prominently to the curriculum is obviously far from aiming to turn all of the future generations into coders. It is simply just to raise awareness/understanding of computers, and possibly slightly increase the number of coders we produce. It is after all only raising tech so its seen more alongside other key subjects like maths, science, english etc and we haven't all turned out to be mathematicians have we?

The uk has a great history of scientists, writers, artists and also computer scientists, but these days when people talk global tech Silicon Valley always comes up first. Would be good if we started to change that right?

Everything Is Everything.. Change, it comes eventually.



1 comments:

The Wikis don't work

Has there ever been a wiki that actually works, I mean, other than the obvious one?

They seemed to explode on to the scene around ten years ago as the future of on-line collaboration and communication, and quickly became a mainstay of tech companies/projects as their knowledge base and documentation. I have worked on several large tech projects as a consultant over the last decade, and almost all of them treated getting a wiki setup only second to basic infrastructure and version control.

Thing is though, they kinda suck.


A few years ago I was working as a consultant on a large, internationally based project, and found myself thinking about the fragmentation, and frankly the madness, of the variety of communication and collaborative tools that were being used. We had messaging apps, email, about three different ticketing systems and a wiki, which lead me to think more about wikis.

They became popular because they suggested collaborative writing and editing of documents, and I guess a lot of managers grabbed hold of it as a way to get developers passionate about writing documentation and capturing the teams knowledge. But at the end of the day, writing documentation is still just as dull as ever - developers still won’t enjoy it, even if it is in a wiki rather than a Word doc. And assuming you are able to get them to write the docs in the first place, there is no user engagement or incentive to keep it up to date. The second someone actually finds something on the wiki isn't correct/working, they will just go ask someone.

Personally, I like the Q’n’A site model a la StackOverflow.com. It doesn't fit across the board (still a place for more formal documentation etc), but it seems like a much better model for capturing company/project knowledge.

Wikis don’t seem to offer much over normal documentation approaches (and seem to offer less than something like Google Docs, which would seem to have superior collaborative tooling).

Forums would offer a more conversation lead approach, which I think would increase user engagement, but it can be hard to find answers amongst a sequential conversation thread.

A Q’n’A site seems to offer the best, with a more conversation based approach for a better, more engaging user experience, but with crowd sourced, peer-verified answers, making it easy to find the answer you are looking for. Throw in the gamification approach StackOverflow uses for good measure and I suspect you may see your knowledge capital growing pretty quick.


It surprises me that there isn't an established, open-source Q’n’A product.

Someone should build one.



0 comments:

Boss MVC - A Lightweight Coldfusion MVC Framework

I don't normally do side-projects using ColdFusion, but one night some time last year, after drinking some neat vodka, I ended up playing around with ColdFusion and building an MVC framework.

The code isn't by any means production ready, and is only the product of two nights (and several glasses of vodka) but it was an experiment into what kind of nice MVC framework type functionality could be exposed in CF.  I have only ever used Fusebox, which as an MVC framework is found wanting in many instances, however, I know there are lots of other MVC frameworks in CF, that undoubtedly have nicer features.

Anyway, it's all over on my GitHub, but I thought I would re-post the details here. Just for funsies.

Some of the main things I wanted to experiment with were involved with simplifying of the framework and removal of boiler plate code. E.g. :

  • Annotation or config defined mapping for URL > Controller methods
  • Simple returns from controllers - just returning view name and model data (to remove the temptation of building HTML code in controllers - a clearer separation of controller and view
  • clearly & appropriately scoped variables in the views (everything to local, as under the hood, everything is being rendered from a CFC, so if you don't local scope the view then you may get surprises)

Controllers:

At the moment, it is dead simple to configure, just grab the framework and create a controller as follows (it assumes that there will be a directory in the root of your webapp called controllers)
/controllers/Home.cfc:
/**
 * @Controller
 **/
component output = "false"  {

    /**
     * @RequestMapping
     **/
    public Array function default( Struct resourceParams="" ){
        return [ "homepage" ];
    }
}
The above code will direct all requests to the application root ("/") to the default() function. The URL pattern for either the @Controller or @RequestMapping can be left blank (or populated) - the values provided are concatenated to produce the URL mapping for a function.
You can also have variable sections of the URL: /controllers/User.cfc
/**
 * @Controller /user
 **/
component output = "false"  {

    /**
     * @RequestMapping /:username
     **/
    public Array function default( Struct resourceParams="" ){
        return [ "userpage" ];
    }
}
In the above example, you can see that @Controller and @RequestMapping have a URL pattern defined. You will also note the @RequestMapping has a ":" before username - this indicates a variable section of the URL. This code will handle requests that hit the URL /user/rob etc - Any named variable section of the URL will be available to the controller function in teh resourceParams struct (as seen above).

Views:

View definition and resolution is also real simple (hopefully). Firstly, you can define a view layout by name - this defines a named view and CFM template, along with any templates that make up the overall view. This is all configured in JSON notation.
At startup, the framework scans the /views directory for any "*.config" files - any it finds it loads up, and then the views defined will be available for use in the application.
/views/view-layout.config:
[
    {
        "name": "homepage",
        "template": "home.pagetemplate",
        "include": {
            "header": "home.header",
            "body": "home.body",
            "footer": "home.footer"
        }
    },
    {
        "name": "userpage",
        "template": "user.pagetemplate",
        "include": {
            "header": "user.header",
            "body": "user.body",
            "footer": "user.footer"
        }
    }
]
The above defines two views, "homepage" & "userpage" - both are made up of similar components. The convention for the templates is relative to the /views directory, and uses "." instead of "/" (e.g. "template": "user.pagetemplate" will expect a file /views/user/pagetemplate.cfm ).
As you can hopefully work out from the above, the "homepage" view is based on /views/home/pagetemplate.cfm and is made up of the three templates /views/home/header.cfm, body.cfm, footer.cfm.
All nested templates are simply placed in the local scope (for the template being rendered), so our pagetemplate cfm looks like this:
/views/home/pagetemplate.cfm:
<html lang="en">
    <cfoutput>#local.header#</cfoutput>
    <body>
        <cfoutput>#local.body#</cfoutput>
        <cfoutput>#local.footer#</cfoutput>
    </body>
</html>
Once we have built a view definition, and have created our templates, a controller simply has to return the viewname as the first argument of an array. If we look again at our Home controller:
/controllers/Home.cfc:
/**
 * @Controller
 **/
component output = "false"  {

    /**
     * @RequestMapping
     **/
    public Array function default( Struct resourceParams="" ){
        return [ "homepage" ];
    }
}
We see that we just want to render the "homepage" view for all requests. Simple controller & simple view composition. Pretty boss.

Models:

Obviously, most of the time we will want to pass data (in the form of a model) to our views for rendering, this is also really simple!
We have seen that in the controller, if there are variable names in the URL that is passed to the controller function in the arguments.resourceParams struct - That data is also automatically passed through to the view template, but can be supplemented by any data accessed in the controller.
Let's look again at out User controller, but lets say we want to pass some additional data to the view for rendering:
/controllers/User.cfc:
/**
 * @Controller /user
 **/
component output = "false"  {

    /**
     * @RequestMapping /:username
     **/
    public Array function default( Struct resourceParams="" ){
        return [ "userpage", { greeting: "Yo!"} ];
    }
}
This time, we are returning a second element in the array - this is a Struct of the model data, this Struct could contain any data you have fetched in the controller that you want to pass to your view template for rendering. As we have a variable URL section (username) and are passing some model data back to the view, both of these can be used.
/views/user/body.cfm:
<h1><cfoutput>#local.model.greeting#</cfoutput> <cfoutput>#local.model.username#</cfoutput>!</h1>
The URL variable sections and the returned model data are all available to the templates in "local.model".

0 comments:

Flat Design (& Android)

"Flat" is currently a big design trend, with pretty much all the big players getting involved.  One of the earliest big-hitters in the field was an iOS app called LetterPress (incidentally, the designer behind this has recently been working on Facebook's "Paper" app - which is also a pretty nice experience)

http://www.atebits.com/letterpress/

The trend found a surprising champion in Microsoft with their Windows Metro look (Windows 8, Windows mobile, xbox), before Apple(iOS 7) later joined the party as Jonny Ives took responsibility for software design as well as hardware. Now many of the most popular sites are sporting a flat look (Google flattened its logo, twitter went flat, even NerdAbility.com is sporting a flat design).

Flat design is about being more minimalist and user-focused - it skips the fanfare of effects or lifelike details for apps/backgrounds/controls and favours simple, clean, crisp minimal interfaces. It's kind of the opposite to the skeumorphic approach - which is using lifelike textures/look&feels for things (the obvious examples being on iOS pre-7 where the contacts have graphics in the background that make it look like a leather address book, or the notes app that has a lined paper background etc).  It avoids fancy 3-d fonts and elements, avoids shading, shadowing, textures - and just uses simple colours, fonts, shapes to quickly convey meaning (see letterpress image above - no fancy rounded corners, fonts or textures - just simple block colours).


Flat Android Design

There is no reason why you can't design an Android app following flat trend, in fact lots already have - Thankfully, as a core part of the flat trend is simple, it is simple to build flat looking apps in no time at all.

Fonts

There isn't any hard and fast rule on fonts really - obviously it should be simple, clean and understandable - for this reason, clean, light san serif fonts have been a common font style to use. The most famous, as used by Microsoft, is Open-Sans - this is the font used across their Windows8 OS. It's popularity also boosted by the fact that it is freely available on Google Fonts, so has swept the web in a fairly big way.



Thankfully, as it happens, Android (since 3.0) has come with packaged with a lovely san-serif font called Roboto. The range of weights, especially the thin and bolder weights allow you to achieve similar aesthetics in line with common flat design, whilst presenting a professional, clean & simple typography.  The obvious disadvantage of using the font is as it's built into later Androids, it's fairly widely used.  Personally, I like to use it. I use the default Android font largely across my apps, and if I want to add a bit of character to a heading/title then I opt for the thinner version of the font.


Buttons

Buttons are an interesting one.  Whilst the flat trend is becoming more pervasive, there are still questions regarding buttons. Buttons have always been skeuomorphic by design - the shading and texture to show a raised/bevelled button (like a real life button that you might press) is classic skeumorphism, and whilst this is simple to switch to a 2-D, flat look&feel, there are still arguments as to whether you should do this - as the button look and feel communicates to the user that it is a button - it is so widely accepted a metaphor, people seem concerned that without the detail, people may not understand it is a button. How can they tell if something is a button or just a coloured block quote? (see this stackexchange question on the topic)

http://www.nngroup.com/articles/windows-8-disappointing-usability/

 Above is an example from Windows 8 controls - as pointed out on the StackExchange link, all of those icons are actually buttons, along with the "Change PC Settings" - That could be fairly confusing, and would be an example of how not to design flat buttons.

Personally, I like flat buttons - as long as you take care to design the page so that the buttons are clear, and the form/page obeys general good UI heirarchy - an example of a simple form I was creating for an app with simple flat buttons is below:


As you can see, designing forms/controls that obey standard UI heirarchy and normal metaphors then it is still incredibly simple and clear what are buttons are what aren't. (I know it doesn't look like a fancy form - there are other decorations elsewhere as well though!)


Colours

There are of course, no rules about colour - but there are trends. A simple google image search for flat colours will give you lots of palettes, and there are also lots of great free tools on the web for building palettes

http://mikehince.com/design/amazing-colour-resources-for-designers/


Adobe's Kuler being a great example (lets you build schemes as well as share them with the community and look at other schemes)



1 comments: