Spring 3.1 RESTful Authentication

Lately I’ve been dabbling in trying to secure a REST service that I’ve built using Spring & Spring Security. I’ve been reading quite a bit about REST of late(and have been for quite some time), and the popular themes around security I’m noticing, is that HTTPS is a good thing, and persisting any sort of session state(even user authentication) is not the best practise. So I decided to take a look at what Spring have provided in the way of authentiction when using web apps, and decided that there wasn’t anything pre-configured that I could use that would require me to provide my security credentials on every request, and effectively re-authenticate, unless of course you were going to use Basic Authentication, or Digest authentication.

Looking around at how others in the industry implement security for their REST services, I came across a pretty neat implementation at Kayako, and thought I’d adopt the same principle. If you’ve not seen how Kayako secure their REST services, its quite simple. You, as a client, need to provide 3 things.

1. The API Key

Something that identifies you as a user. Preferably this should be some “Not so easily guessable” string. I would suggest perhaps some guid. Add this as an additional attribute against the user details you hold in your DB. Allow the user to request a new guid through your web app if they feel that their current one has been compromised.

2. A Salt

This should be a random string that should change on every request. You could calculate and MD5 hash of the content of your request, or you could send any other random string.

3. Signature

This is the Hash(preferably a HMAC SHA, see my previous post about hashing passwords in Spring). This hash is a combination of your password, with the Salt mentioned above. On the server side, it’ll lookup your user details via your API Key, and validate the authenticity of your credentials by performing the same hash against your salt/password in the hope that it’ll arrive at the same signature that you’ve provided in the request. Obviously the password that is stored in the database would be a hashed password anyway, just so that it’s not obviously “guessable”.

I couldn’t find anything in Spring which is provided out of the box support for stateless authentication for REST, where I could provide these credentials in the URL, so I decided it would be fun to try and roll my own, using Kayako as a source of authority on how to provide the details for the secured REST call. Feel free to check out the sample app I’ve put together over on Github.

Whats Involved

In order to embark on creating your own mechanism for authentication with Spring, you need to be familiar with how the Spring Security model works. If you’re not familiar with it, I’d suggest a quick read over their documentation.

The main java classes involved in order to make this happen are the following:

1. The Filter (RESTAuthenticationFilter)

I’ve chosen to insert this filter where Spring would have used a Forms Authentication Filter. Below is a snippet where I’ve pointed out where/how I did this.


<sec:http disable-url-rewriting="true" entry-point-ref="forbiddenEntryPoint" use-expressions="true" create-session="never">
 <sec:anonymous enabled="false"/>
 <sec:session-management session-fixation-protection="none"/>
 <sec:custom-filter ref="restAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
 <sec:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
 </sec:http>

Notice how I’ve chosen specifically to not create a session, disabled anonymous access, and replaced the Forms Login Filter with my own.

2. The Authentication Provider (RESTDaoAuthenticationProvider)

This is essentially responsible for looking up the user, and validating their credentials. I’ve tried to use as much of already existing functionliaty so I’ve extended from the AbstractUserDetailsAuthenticationProvider, and the most important method here is the additionalAuthenticationChecks(...). This method is actually where the check is done to see if the password the user has supplied is in fact correct.

So thats the guts of it! There are obviously a few other supporting classes, but if you can get your head around this, then you’re well on your way to customising your authentication for REST Services in Spring.

Advertisements

Hash based Message Authentication Code hashing in Spring MVC

Hash based Message Authentication Code(HMAC) is used in scenarios where you need to validate the validity and authenticity of a message. Recently I was implementing some security aspects for our REST service, and I noticed that Spring Security currently supports SHA hashing for password, but no HMAC SHA hashing.

Now firstly, this is really for informational sakes, and I’m in no position to advise which way is better, but instead, I’m providing what I think I’d rather have implemented, and its purely a personal preference – for me anyway.

So, now back to the point. Firstly, below is a sample of a security configuration(in xml) using one of the many Spring Security provided implementations of the PasswordEncoder interface – namely the ShaPasswordEncoder.

.....
<authentication-manager>
   <authentication-provider>
      <password-encoder hash="sha"/>
      <user-service>
         <user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" authorities="ROLE_USER, ROLE_ADMIN" />
         <user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f" authorities="ROLE_USER" />
      </user-service>
   </authentication-provider>
</authentication-manager>
.....

Now in this simple contrived sample config, we’re telling Spring Security to use their implementation of the ShaPasswordEncoder. Upon inspection of this implementation, you’re also able to specify the field responsible for holding the salt value if you so choose to provide one. In the REST service I have, I have defintely opted to provide a salt in which to further secure the hash.

In this ShaPasswordEncoder implementation provided by Spring, it performs a hash on the raw concatenated string in the format of “password{salt}” . This surprised me somewhat, because I had actually expected Spring to provide an implementation of HMacSHA when providing a salt, not just an implementation of SHA! And believe me theres a difference! So the purist in me came out, and I couldn’t let this rest (see what I did there? rest….REST?.. ok I know, perhaps a little lame, but I digress.)

The main difference between the two implementations, is that the way Spring have done it, they have just effectively hashed a string. With HMac, the salt actively plays a role in the encryption of the raw string. Some might argue that they arrive at the same end result, which is a hashed string based on the salt. I’d tend to agree, but the purist in me wanted to do it properly, so I wrote my own implementation of what the HMacSha should have been. Below is a simple snippet of what the code looks like when just using a normal SHA hash, and when using a HMacSHA. In these samples below I’ve only shown the code which actually does the hashing so you can see what the difference is. Also bear in mind, that my custom rolled hashing class extends the PasswordEncoder class so that I can include it in the security config xml.

SHA Implementation

public String encodePassword(String rawPass, Object salt) {
 String saltedPass = mergePasswordAndSalt(rawPass, salt, false);

MessageDigest messageDigest = getMessageDigest();

byte[] digest = messageDigest.digest(Utf8.encode(saltedPass));

// "stretch" the encoded value if configured to do so
 for (int i = 1; i < iterations; i++) {
 digest = messageDigest.digest(digest);
 }

if (getEncodeHashAsBase64()) {
 return Utf8.decode(Base64.encode(digest));
 } else {
 return new String(Hex.encode(digest));
 }
 }

protected final MessageDigest getMessageDigest() throws IllegalArgumentException {
 try {
 return MessageDigest.getInstance(algorithm);
 } catch (NoSuchAlgorithmException e) {
 throw new IllegalArgumentException("No such algorithm [" + algorithm + "]");
 }
 }

protected String mergePasswordAndSalt(String password, Object salt, boolean strict) {
 if (password == null) {
 password = "";
 }

if (strict && (salt != null)) {
 if ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1)) {
 throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
 }
 }

if ((salt == null) || "".equals(salt)) {
 return password;
 } else {
 return password + "{" + salt.toString() + "}";
 }
 }

HMac Implementation

protected final Mac getMac() throws IllegalArgumentException {
 try {
 return Mac.getInstance(algorithm);
 } catch (NoSuchAlgorithmException e) {
 throw new IllegalArgumentException("No such algorithm [" + algorithm + "]");
 }
 }
 public String encodePassword(String rawDataToBeEncrypted, Object salt) {
 byte[] hmacData = null;
 if(rawDataToBeEncrypted != null){
 try {
 SecretKeySpec secretKey = new SecretKeySpec(rawDataToBeEncrypted.getBytes(ENCODING_FOR_ENCRYPTION), this.algorithm);
 Mac mac = getMac();
 mac.init(secretKey);
 hmacData = mac.doFinal(salt.toString().getBytes(ENCODING_FOR_ENCRYPTION));

if (isEncodeHashAsBas64()) {
 return new String(Base64.encode(hmacData), ENCODING_FOR_ENCRYPTION);
 } else {
 return new String(hmacData, ENCODING_FOR_ENCRYPTION);
 }

}
 catch(InvalidKeyException ike){
 throw new RuntimeException("Invalid Key while encrypting.", ike);
 }
 catch (UnsupportedEncodingException e) {
 throw new RuntimeException("Unsupported Encoding while encrypting.",e);
 }
 }
 return "";

}

I am using this version of the hashing algorithm for my sample REST service which I have up on Github. You can check out the java file itself here, but I’ll give a more detailed run down of the sample project in my next blog post, which is about supporting stateless authentication in a Spring REST application, and how I went about rolling my own security filter/mechanism to support this. Watch this space!

Overriding Spring Beans in a Servlet Context

A neat little trick I’ve recently picked up is the ability to override spring bean definitions in a web application, but inside the servlet context. I was always under the impression that only one spring application context was loaded for the entire web application, but in fact it appears that its actually loaded for each DispatcherServlet you have registered in your web.xml. I know, a slight oversight on my part. To be fair, most web apps I’ve worked with have only had one DispatcherServlet declared, so perhaps I can be forgiven for my short sighted ignorance 🙂

I’m definitely no Michealangelo when it comes to anything graphic, but here is a quick diagram illustrating what I’m going on about.

Illustration of how to override a spring bean definition to provide a custom bean for that Dispatcher Servlet application context.

The crux of this example lies in the web.xml.


<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/default-spring-context.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>spring-mvc-default</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring-mvc-default</servlet-name>
<url-pattern>/default/*</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>spring-mvc-custom</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/default-spring-context.xml,classpath:/dispatcher-context.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring-mvc-custom</servlet-name>
<url-pattern>/custom/*</url-pattern>
</servlet-mapping>

</web-app>

Notice how the spring-mvc-default has its contextConfigLocation init-param value set to nothing, leaving it up to the ContextLoaderListener to load it from the declared ContextParam declared in the beginning, and also how the spring-mvc-custom has it’s contextConfigLocation init-param value of set to the default and the dispatcher specific config file.

I’ve found this quite useful in some of the web apps I’ve been building where I need a specific type of bean to be injected instead of the default one declared. Something to also note here is that in each ServletContext(i.e. each DispatcherServlet definition), they cannot see the customised beans that are being used by any of the others. Each DispatcherServlet loads its own isolated Application Context.

Update: If you’d like top see this in action, albeit a very contrived example then head over to github here,

REST vs SOAP services – How I made my choice.

During a recent bout of product development, we were faced with a task of how to get massive amounts of financial data into our database. Bearing in mind, that our product is driven by client data which is pumped into it, we needed to find a way to expose a public facade, to authorised users only, in order for them to pump this data through. Oh, and our clients could prefer using other technologies for sending this data. i.e. .NET,Java, Ruby etc.

After much investigation I settled implement REST services through Spring. These were my top 3 reasons, of course I had a lot more, but these really stood out for me.

1. Low entry point and lightweight.

How many times have you heard this? But it’s true! Its just the HTTP stack you need. I unfortunately am constrained with time(aren’t we all?!) and I don’t really want the hassle of having to deal with massive unreadable SOAP packets, not to mention the toolkits I’ll need along with over-bloated configuration that goes along with it! I might be unfairly judging SOAP web services here, but I’ve never really had a pleasurable experience implementing SOAP in the past, especially when I have to keep in mind that the clients we’re relying on to use this platform could be clients who employ software developers of  varying degrees, so most of all I want to keep interfacing with our system as easy as possible.

2. Convention over configuration.

When developing REST like services, you have to adhere to simple URL’s otherwise no one is going to want to use it, and it makes things much simpler. I for one really don’t want to have to remember a massive URL just to add one record to a customer’s details. Adopting this approach really forces you to take a step back and think about how you represent your data, and how you plan to manipulate it. Doing that I’ve found has actually provided a better view of how our domain entities relate to each other, and their dependencies become transparent.

3. Authentication and Authorisation

I know many would argue that SOAP WS-Security is probably the most secure way to go, but to be completely honest, all my communication is going to take place over https and https only. What more do I need?  Implementing Authentication and authorisation over REST is just as secure, provided you make sure you don’t cut any corners, and not only that, it’s also simple if all you’re going to be doing is relying on already existing web authentication mechanisms. i.e. BASIC, FORM etc… I however have decided to implement my own authentication mechanism in Spring. Watch out for it in my next blog post.

4. Discoverability

OK, I know, I said top 3, but I couldn’t resist not mentioning this one. And its about being able to easily include self discovery of services while using REST services. And I must admit, this also played a big role in me making the decision to use REST for the kind of services we provide. REST in Practice really goes a long way in advocating explorable services through hypermedia, and I would urge anyone who is considering REST to give it a read. And if you find yourself racing through that book, then get yourself the REST API Design Rulebook which will help guide you in making the right choices when build your REST service.

Next up, how to authenticate the user in a REST kinda way….

JSR303 + Spring MVC + Selective Validations

If you’ve ever been using the JSR 303 bean validation in Spring MVC, using the @Valid annotation inside your controllers, you’ve no doubt been frustrated somewhat by the lack of support for selective bean validation. What I mean by this is that in some cases(in reality most cases!) when you validate a bean, you want control over what gets validated and when.

In the past, one of the ways to overcome the @Valid running all of your validations was to either use different model objects or to whip up your own custom version of the @Valid annotation, which isn’t the cleanest way to go about it if you ask me. It’s just to open to errors.

Well thankfully, with Spring 3.1, there is now the introduction of the @Validated annotation which you can use in place of @Valid. We now have the opportunity to specify “groups” to validate. So typically, when you’re applying the bean validation to your model object, it would usually look something like this:

public class UserDTO {

@NotBlank(message = "Username must be supplied.", groups = {Default.class, MinimalUserValidation.class})
@Length(min = 6, message = "Username must be at least 6 characters long.")
private String username;

@NotBlank(message = "Password must be supplied.", groups = {Default.class, MinimalUserValidation.class})
private String password;
private String confirmPassword;

//Rest of class definition ommitted for brevity
}

Notice how on line 3 & 7, we have now specified the groups value, and have provided it with marker interfaces, declaring that these are the validations we’d like to have run when any one of these marker interfaces are mentioned within our @Validated annotation.

So, if we only wanted to run the MinmalUserValidation marked validations, then this is what your controller method would look like:


@RequestMapping(value="/add-user-partial.html", method = RequestMethod.POST)
public String createNewUserWithPartialValidation(@Validated(value = MinimalUserValidation.class) UserDTO userDTO, BindingResult bindingResult, Model model){
// Method body omitted for brevity
}

And thats all there is to it. I have a sample project on Github here if you want to check it out.

As a side note – For the curious amongst us, you’ll soon notice after digging around a bit on the constraint annotation interface (check out the javax.validation.constraints.AssertTrue for an example), you’ll see it includes a <code>payload</code> attribute. After a bit of google goodness, I came across this blog post which provided the answers I was looking for. 🙂

Different Responses with Spring REST

So lately I’ve been delving into Spring REST, and playing around with a few things, and something dawned on me which hadn’t occurred to me until I was actually messing around with a side project I have going on at home. Spring provides you the capability to return content in 2 different fashions:

  1. Either as a representation of the Model Object OR
  2. Either as the actual formatted content in the response body in whatever format(xml, json etc)

It’s important to draw the distinction between information being returned to you directly via the response body, and the model object. An example is probably in order.

Let’s say we have our standard Spring MVC project set up, and we have the controller class HomeController

@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value="/home", method=RequestMethod.GET)
public String home(ModelMap model) {
logger.info("Welcome home!");
model.addAttribute("attribute", "home-gerome");
return "home";
}
}

and the relevant xml for the spring configuration looks like this:

<bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="autodetectAnnotations" value="true"/>
<!--<span class="hiddenSpellError" pre=""-->bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1"/>
<property name="mediaTypes">
<map>
json" value="#{T(org.springframework.web.servlet.view.json.MappingJacksonJsonView).DEFAULT_CONTENT_TYPE}"/>
<entry key="xml" value="#{T(org.springframework.web.servlet.view.xml.MarshallingView).DEFAULT_CONTENT_TYPE}"/>
</map>

</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg name="marshaller" ref="xStreamMarshaller"/>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true"/>
</bean>

There’s nothing special about this configuration, its pretty standard, and I managed to gleam most of it off of the Spring documentation, and the API docs on the ContentNegotiatingViewResolver

Notice how there’s only a @RequestMapping annotation on the method, nothing else, and the ModelMap parameter being passed in. If you build your HTTP GET request ( I use an add-on called REST Client for Firefox), for the home.json resource, you’ll notice that the response body actually returns like this:

{"attribute":"home-gerome"}

No surprises here that is looks just like the content of the Model, with the key-value pair.

I’d just like to mention that if I made a request for home.html, instead of home.json, I’d actually get the HTML content of the home.jsp page in the response body, and there will be no trace of the ModelMap data here. This is purely down to the ViewResolver chaining where the ContentNegotiatingViewResolver wouldn’t be able to satisfy my request for my .html request, and would then move onto the 2nd ViewResolver I had configured which can. Seeing as though I made the request for home.json, the ContentNegotiatingViewReolver finds a class that can resolve a view for the request, and it uses the MappingJacksonJsonView to resolve the request and format a response, which looks at the ModelMap, to return data back to the calling client. Requests ending in .json, or .xml etc are preferred over the Accept Headers in the request, although this is also configurable in the ContentNegotiatingViewResolver.

Also, you’ll see I’ve added the property ignoreAcceptHeader=true, and I did that because of another “problem” I faced while working with HTTP requests and how Spring uses them to make certain choices, and subsequently learnt that HTTP Headers can be evil… but more on that in another post. So for now, I’ve actually set this property in my project to ignore Accept Headers for now, and just use the extensions on the request to determine how content should be delivered.

Now, having spring deliver content via the @ResponseBody opens up another can of worms. In fact, I was going to try and give you an example here, but after I finished I felt that this post actually ended up being way too massive so I’ll possibly address @ResponseBody use and configuration in an upcoming post. Suffice to say though, that although it is nice to have your objects returned directly via the response body when using the @ResponseBody annotation, doing so doesn’t come without its fair share of additional configuration and hacking about.

In chatting to some others who have used Spring REST, and all the goodness it offers, I’ve come to the conclusion that many are left with the question of when to use @ResponseBody as opposed to just the traditional way before @ResponseBody came onto the scene. From what I’ve seen so far, I’d make the decision based on the following

You have an existing Spring MVC website in place, and you want to make it deliver content in json and xml format.

Well, if this is the case, I’d avoid using @ResponseBody, and I’d just populate the ModelMap object with the content I want to send back to the client. The reason for this being that, I can still then make use of the view resolving that happens for me when I return a string to lookup the .jsp page and render that content back. However if I stick a @ResponseBody tag on my method, I’m effectively responsible for doing all of that myself, i.e. returning the actual content to the response, and I lose all that spring automagic that happened before. So for situations where you want to run your website and your REST requests/responses off of the same MVC controller, then I’d stay away from @ResponseBody.

Another good reason for avoiding the @ResponseBody, is that for GET requests, Spring doesn’t seem to be able to work out (yet) which formatter to correctly pick other than looking at the accept headers. When you use @ResponseBody, as part of the configuration, you’ll setup HTTPConverters responsible for formatting the content, and you’ll configure them to only listen for certain accept headers by populating the supportedMediaTypes property. As I’ve mentioned just previously, I’ve just recently learnt that when relying on browsers coming to your website, accept headers can be evil.. so stay away! 🙂

You don’t have to service browser requests, and will only be serving content to clients to have control the accept header.

If all you need is something that interacts with a representations of your domain objects, then I’d say go for the @ResponseBody annotation. Purely because clients are more than likely in control of setting things like HTTP headers, and when using @ResponseBody with GET requests especially, you have to add the headers property of the @ResponseBody annotation to tell spring which method to effectively call for which type or representation. So your controller would look something like this:

These are my experiences so fat while using @ResponseBody. I’ve only just started realising its benefits, but I think it needs to be said that if you;rethinking about using the @ResponseBody feature, think carefully about where, and how you want to use it, because it can give you more headaches than its worth.