简体   繁体   English

寻找建议来保护用python-flask编写的私有REST API

[英]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. 我目前正在使用微框架Flask在python中编写一个rest API。 It's a private API and it deals with user data . 它是一个私有API,它处理用户数据 I plan to use this API to build a web and an Android app. 我计划使用此API来构建网络和Android应用。

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. 例如,如果您想使用用户bob在我的服务上发布数据,您可以在myapi / story / create上发布请求,并使用摘要模式提供bob的凭据。

I am aware this is not a good solution because : 我知道这不是一个好的解决方案,因为:
-Digest auth is not secure -Digest auth不安全
-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. 我阅读了很多关于oAuth的内容,但是三脚认证似乎有点过分,因为我不打算向第三方开放我的API。
The 2-legged oAuth won't fit because it only provides authentification for clients and not for users. 2脚oAuth不适合,因为它只为客户提供身份验证,而不是为用户提供身份验证。
Another problem with oAuth is that I haven't found a comprehensive guide for implementing it in Python. oAuth的另一个问题是我没有找到在Python中实现它的综合指南。 I found the python-oauth2 library, but I don't understand the server example and I can't find additional documentation. 我找到了python-oauth2库,但我不了解服务器示例,我找不到其他文档。 Plus it seems that many aspects of oAuth are not covered in this example. 此外,似乎oAuth的许多方面都未包含在此示例中。

So my questions are : 所以我的问题是:

  1. Is there alternative scheme (not oAuth) for authenticate both client and user with a reasonable level of security ? 是否有替代方案(不是oAuth)用于以合理的安全级别对客户端和用户进行身份验证?
  2. If oAuth is the best solution : 如果oAuth是最好的解决方案:
    • 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? 是否有python-oauth2或任何其他Python库的详细文档?

Any help or advice will be appreciated. 任何帮助或建议将不胜感激。

The simple answer is to expose your API via HTTPS only, and then use HTTP Basic authentication. 简单的答案是仅通过HTTPS公开您的API,然后使用HTTP基本身份验证。 I don't think there's really any reason to bother with Digest. 我认为没有理由去理解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. 通过HTTPS隧道传输,您可以获得安全连接。

If you want to authenticate the client, you could use SSL client certificates. 如果要对客户端进行身份验证,可以使用SSL客户端证书。 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. 也就是说,一般来说真的很难将客户端锁定在恶意用户身上,所以我会考虑让注册功能公开访问,并通过带外帐户验证保护自己免受DOS等攻击。

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. 我还没有使用你提到的框架,但我使用基本的auth来保护基于web.py的应用程序中的一些网址并且工作正常。

Basically, you can use a token in base64 which is actually a standard http heeader. 基本上,你可以在base64中使用一个令牌,它实际上是一个标准的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

If you are interested in basic authentication, here is a quick attribute which you can use to decorate your handlers http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute . 如果您对基本身份验证感兴趣,可以使用以下快速属性来装饰处理程序http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute This example is primarily written in web.py context, but I guess it can be easily tweaked. 这个例子主要是在web.py上下文中编写的,但我想它可以很容易地调整。

def check_auth(username, password): 
    return username == 'username' and password == 'password'


def requires_auth(f):
    @wraps(f)     
    def decorated(*args, **kwargs):        
        auth = web.ctx.env['HTTP_AUTHORIZATION'] if 'HTTP_AUTHORIZATION' in  web.ctx.env else None
        if auth:
            auth = re.sub('^Basic ', '', auth)
            username, password = base64.decodestring(auth).split(':')
        if not auth or not check_auth(username, password):
            web.header('WWW-Authenticate', 'Basic realm="admin"')
            web.ctx.status = '401 Unauthorized'
            return 

        return f(*args, **kwargs)

    return decorated

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM