spring-hmac-rest

Spring HMAC authentication filter for RESTfull webservice example.

Client sends frollowing http request to the server:

POST /api/echo HTTP/1.1
Accept: application/json, application/*+json
Content-Type: application/json
Date: Thu, 29 Oct 2015 05:27:23 GMT
Authorization: HmacSHA512 user:4314efa9-04c2-4109-a6a6-385797fa47a3:p0Mi/le2ph0XTwmnRZ8+IVf1D3kAbos14eJLeuL/Y8zpbV7tp1+4lmqgqtU9Z6XlBa3YylMD+Mdu+4RNcc6Y5w==
User-Agent: RestAPI client v.1.0
Content-Length: 24
Host: localhost:8080

{"data":{"name":"hoho"}}

The Authorization header format is:

Authorization: HmacSHA512 <user>:<nonce>:<digest>

where digest is Base64 formatted HMAC SHA512 digest of the following string:

METHOD\n
SCHEME\n
HOST:PORT\n
RESOURCE\n
CONTENT_TYPE\n
USER\
NONCE\n
DATE\n
PAYLOAD\n

i.e. string to sign is:

POST\n
https\n
localhost:8080\n
/api/echo\n
application/json\n
user\n
4314efa9-04c2-4109-a6a6-385797fa47a3\n
Thu, 29 Oct 2015 05:27:23 GMT\n
{"data":{"name":"hoho"}}\n

where user="user" and secret="secret".

Java client code example:

ApiClient client = new ApiClient("localhost", 8080);
client.setCredentials("user", "secret");
client.init();

Foo request = new Foo("hoho");
FooResponseWrapper response = client.echo(request, FooResponseWrapper.class);

In PHP there is a function hash_hmac for generating keyed hash value using the HMAC method. Here is the example:

<?php

$api_key = 'user';
$api_secret = 'secret';
$nonce = '4314efa9-04c2-4109-a6a6-385797fa47a3';

$string_to_sign = 'POST' . "\n" .
    'https' . "\n" .
    'localhost:8080' . "\n" .
    '/api/echo' . "\n" .
    'application/json' . "\n" .
    $api_key . "\n" .
    '4314efa9-04c2-4109-a6a6-385797fa47a3' . "\n" .
    'Thu, 29 Oct 2015 05:27:23 GMT' . "\n" .
    '{"data":{"name":"hoho"}}' . "\n";

$digest = hash_hmac('sha512', $string_to_sign, $api_secret, true);
$header = 'Authorization: HmacSHA512 ' . $api_key . ':' . $nonce . ':' . base64_encode($digest);
echo $header;

See ApiClientTest

Links