Code Monkey home page Code Monkey logo

twolegged's Introduction

Twolegged

Important Note: WIP!

A framework agnostic library for implementing two-legged authentication to secure internal APIs by verifying signed requests using a key and a shared secret.

Why?

I was looking for something better than Security through obscurity to secure internal RESTful APIs without the need for,

  1. users to grant access to the client (as the data is not tied to resource owners).
  2. the clients to obtain temporary access tokens (as in case of "Client Credentials Auth Flow" of Oauth 2.0) from the server as both servers and clients are entirely controlled by us.

Since I was working with Flask, the first thing I tried was Flask-oauthlib which supports three-legged OAuth 1 flow and it was quite tricky to fit a simple two-legged flow into it. So, I wrote a couple of functions to verify a signed request using existing libraries.

Dependencies

Usage

Let's first briefly understand the flow before getting to the usage:

  1. The client/consumer will sign the request (HMAC-SHA1 method) with a key-secret pair that the server also knows. The key is included in the request headers whereas the secret is never sent to the other side.
  2. The provider will identify the client from the key and use it's secret to verify the signed request.

We will get to point 1 later. For point 2, all that's required is a call to the function twolegged.validate_request which abstracts away the verfication of the request.

validate_request takes two arguments:

  • First, a request object that implements the interface defined by twolegged.Request class. The easiest way to do this is to subclass this class and implement all the methods that raise NotImplementedError to wrap the request object provided by whichever web framework you are using with this interface eg. the thread local Flask request object or the Django request object passed as an arg to the views. This way, the lib can be used with any framework.

    Note: All values including the list items and key-values in dicts returned by these methods must be unicode

  • Second, a function (consumer_getter) that takes a string which is the key or the unique identifier of the consumer. The job of this function is to use the identifier to lookup a consumer from whichever storage your application might be using eg. relational database, a text file etc. and return a dict with the fields "key" and "secret", both as unicode. If a consumer with the given key is not found, it should return None

See the example implementation for Flask in examples/flask_api_auth.py which loads the consumer info from a file. A decorator protect_api is also included that can be applied to the views. Similar Request object wrapper, consumer_getter function and decorator can be implemented for Django or any other framework for that matter.

Ok, so now that the api endpoints are protected, on the client side (point 1), we would now need to sign requests so that the provider accepts them. For this, we can use the requests-oauthlib library by specifying both the resource owner key and secret as None. An example can be found in examples/client.py

Todo

  1. Write tests

Caveat

This method assumes that both the client and server can permanently store a key-secret pair at their end and so it's best suited for communication between a backend server and a front app server. DONOT use this method if your application resides on the user's device/machine or the source code is distributed to the users which might cause the secret to be exposed. In that case, the Client credentials flow of OAuth 2.0 might help.

License

MIT

twolegged's People

Contributors

naiquevin avatar

Stargazers

 avatar M avatar Lee Treveil avatar

Watchers

 avatar James Cloos avatar M avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.