15

我目前正在使用微框架 Flask 在 python 中编写一个 rest API。它是一个私有 API,它处理用户数据。我打算使用这个 API 来构建一个 web 和一个 Android 应用程序。

现在我使用摘要身份验证来保护私人用户数据。例如,如果您想使用用户 bob 在我的服务上发布数据,您可以在 myapi/story/create 发出发布请求,并使用摘要模式提供 bob 的凭据。

我知道这不是一个好的解决方案,因为:
-Digest auth 不安全
-客户端未经过身份验证(如何保护与当前用户无关的请求,例如创建新用户?)

我阅读了很多关于 oAuth 的内容,但是 3-legged 身份验证似乎有点矫枉过正,因为我不打算向第三方开放我的 API。
2-legged oAuth 不适合,因为它只为客户端提供身份验证,而不为用户提供身份验证。
oAuth 的另一个问题是我还没有找到在 Python 中实现它的综合指南。我找到了python-oauth2库,但我不理解服务器示例,也找不到其他文档。另外,这个例子似乎没有涵盖 oAuth 的许多方面。

所以我的问题是:

  1. 是否有替代方案(不是 oAuth)以合理的安全级别对客户端和用户进行身份验证?
  2. 如果 oAuth 是最好的解决方案:
    • 如何跳过授权过程(因为用户不必授权第三方客户端)?
    • 是否有关于 python-oauth2 或任何其他 Python 库的详细文档?

任何帮助或建议将不胜感激。

4

3 回答 3

8

简单的答案是仅通过 HTTPS 公开您的 API,然后使用 HTTP 基本身份验证。我认为没有任何理由打扰 Digest。基本身份验证是不安全的,但会随每个请求一起提交,因此您永远不必担心您的身份验证会过时或其他任何情况。通过 HTTPS 建立隧道,您就拥有了安全的连接。

如果要对客户端进行身份验证,可以使用 SSL 客户端证书。也就是说,通常很难真正锁定客户端免受恶意用户的攻击,因此我会考虑让注册功能可公开访问,并通过带外帐户验证保护自己免受 DOS 等攻击。

于 2012-06-03T21:17:12.760 回答
4

您是否已经考虑过使用基本身份验证?

我还没有使用你提到的框架,但是我使用了基本的身份验证来保护基于 web.py 的应用程序中的一些 url,并且工作正常。

基本上,您可以在 base64 中使用实际上是标准 http 标头的令牌。

也许这个例子可以帮助你:

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
于 2011-08-29T13:11:33.627 回答
0

如果您对基本身份验证感兴趣,这里有一个快速属性,您可以使用它来装饰您的处理程序http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute。这个例子主要是在 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
于 2013-01-25T21:25:47.097 回答