Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for advice to secure a private REST API written in python-flask

I am currently writing a rest API in python with the microframework Flask. It's a private API and it deals with user data. I plan to use this API to build a web and an Android app.

For now I use digest auth to secure private user data. For example if you want to post data on my service with the user bob you make a post request at myapi/story/create and provide bob's credentials with the digest pattern.

I am aware this is not a good solution because :
-Digest auth is not secure
-The client is not authenticated (How to secure requests not related with current user, for example create a new user ?)

I read a lot of stuff about oAuth but the 3-legged authentication seems overkill because I don't plan to open my API to third party.
The 2-legged oAuth won't fit because it only provides authentification for clients and not for users.
Another problem with oAuth is that I haven't found a comprehensive guide for implementing it in Python. I found the python-oauth2 library, but I don't understand the server example and I can't find additional documentation. Plus it seems that many aspects of oAuth are not covered in this example.

So my questions are :

  1. Is there alternative scheme (not oAuth) for authenticate both client and user with a reasonable level of security ?
  2. If oAuth is the best solution :
    • How to skip the authorization process (because users won't have to authorize third party clients)?
    • Is there detailled documentation for python-oauth2 or for any other Python library?

Any help or advice will be appreciated.

like image 229
a.b.d Avatar asked Aug 28 '11 23:08

a.b.d


2 Answers

The simple answer is to expose your API via HTTPS only, and then use HTTP Basic authentication. I don't think there's really any reason to bother with Digest. Basic authentication is insecure, but is submitted with every request so you never need to worry about your authentication going stale or whatever. By tunneling it over HTTPS, you have a secure connection.

If you want to authenticate the client, you could use SSL client certificates. That said, in general it's pretty tough to really lock down the client against malicious users, so I would consider making the sign-up functions openly accessible and protect yourself from DOS etc via out-of-band account verification.

like image 188
easel Avatar answered Oct 11 '22 09:10

easel


Have you already considered to use the Basic Authentication?

I haven't used yet the framework you mentioned, but I used the basic auth to protect some urls in an app based on web.py and worked fine.

Basically, you can use a token in base64 which is actually a standard http heeader.

Maybe this example can help you:

class Login:

    def GET(self):
        auth = web.ctx.env.get('HTTP_AUTHORIZATION')
        authreq = False
        if auth is None:
            authreq = True
        else:
            auth = re.sub('^Basic ','',auth)
            username,password = base64.decodestring(auth).split(':')
            if (username,password) in settings.allowed:
                raise web.seeother('/eai')
            else:
                authreq = True
        if authreq:
            web.header('WWW-Authenticate','Basic realm="Auth example"')
            web.ctx.status = '401 Unauthorized'
            return
like image 28
Walter Traspadini Avatar answered Oct 11 '22 07:10

Walter Traspadini