exonum-http-get-auth

Crates.ioexonum-http-get-auth
lib.rsexonum-http-get-auth
version0.1.0
sourcesrc
created_at2017-11-05 10:58:40.714764
updated_at2017-11-05 10:58:40.714764
descriptionAuthenticate HTTP GET requests in Exonum through AWS-like header signing.
homepage
repositoryhttps://gitlab.com/Mangman/exonum-http-get-auth
max_upload_size
id38217
size6,834
(Mangman)

documentation

README

exonum-http-get-auth

Authenticate HTTP GET requests in Exonum through AWS-like header signing.

Exonum already features functionality to auth POST, so you can filter the data added to blockchain. This crate allows you to also authenticate reading.

Request validation is based on signing url, method and timestamp (requests decay in 30 sec after signing to prevent replay attacks) and putting the signature into http header.

Usage:

extern crate exonum_http_get_auth;
use exonum_http_get_auth::get_auth::authenticate_request;

Provided authenticate_request() method returns a function to be passed as an argument into the router's get() handler :

router.get("/my_endpoint", authenticate_request(key, my_endpoint), "my_endpoint");

and a little more more generic way in case you want to authenticate multiple requests with the same key:

let auth = |f| authenticate_request(key, f);
router.get("/my_endpoint", auth(my_endpoint), "my_endpoint");

Front-end side:

Proper request should have fields:

  • x-date date in ISO8601 format

  • x-auth 64-byte SHA256 signature of concated url+method+date UTF-8 array (method is always "GET")

Example:

const Exonum = require('exonum-client');
const lib = require('./lib');

function toUTF8Array(str) {
    var utf8 = [];
    for (var i=0; i < str.length; i++) {
        var charcode = str.charCodeAt(i);
        if (charcode < 0x80) utf8.push(charcode);
        else if (charcode < 0x800) {
            utf8.push(0xc0 | (charcode >> 6), 
                      0x80 | (charcode & 0x3f));
        }
        else if (charcode < 0xd800 || charcode >= 0xe000) {
            utf8.push(0xe0 | (charcode >> 12), 
                      0x80 | ((charcode>>6) & 0x3f), 
                      0x80 | (charcode & 0x3f));
        }
        else {
            //only handle chars up to U+FFFF
            utf8.push(0xef, 0xbf, 0xbd); 
        }
    }
    return utf8;
}

const date = new Date().toISOString();
console.log(date);
const method = 'GET';
const address = 'http://127.0.0.1:8000/my_endpoint';

const keys = Exonum.keyPair();

const data = toUTF8Array(address+method+date);

const signature = Exonum.sign(keys, data);

var reqHeaders = new Headers();
reqHeaders.append('x-date', date);
reqHeaders.append('x-auth', signature);

var options = { method: method,
                headers: reqHeaders,
                mode: "cors" };

var authRequest = new Request(address, options);

fetch(authRequest)
    .then(result => {
        console.log(result.json());
    })
    .catch(error => {
         console.log(error);
}); 
Commit count: 9

cargo fmt