Security in a REST API

Andy Balaam
artificialworlds.net/blog

Contents

Recap

Security Goals

Architecture

Options

Options

HTTP Basic

HTTP Basic

Easy to use on command line too:

$ curl \
    --data '{"title":"Foo", ...' \
    http://localhost:8080\
    /api/v1/poems
    --user 'username:pass'

HTTP Digest

Implementation

Implementation

def GET( self, urlid ):
    user = authenticate_user(
        self.db )
    ...

Implementation

def authenticate_user( db ):
    auth = web.ctx.env.get(
        "HTTP_AUTHORIZATION" )
    if auth is None:
        return None
    user, pw = extract_user_pw( auth )
    ...

Implementation

def extract_user_pw( auth ):
    auth = re.sub(
        "^Basic ", "", auth )

    auth = base64.decodestring( auth )

    return auth.split( ":" )

Implementation

def authenticate_user( db ):
    ...
    if (    user in known_users
        and known_users[user] == pw
    ):
        return user
    else:
        raise unauthorized()

Implementation

def POST( self, urlid ):
    user = require_authenticated_user(
        self.db )
    ...

Implementation

def require_authenticated_user( db ):
    user = authenticate_user( db )
    if user is None:
        raise unathorized()
    return user

Implementation

Implementation

def is_valid_user( db, user ):
    return ( user is not None )

def amendpoem( ..., user ):
    if not is_valid_user( db, user ):
        raise InvalidRequest( 401 )
    ...

Implementation

def amendpoem( ..., user ):
    ...
    if doc["contributor"] != user:
        raise InvalidRequest( 403 )

More info

Videos youtube.com/user/ajbalaam
Twitter @andybalaam
Blog artificialworlds.net/blog
Projects artificialworlds.net