金字塔中的多个认证策略

时间:2015-02-26 11:04:34

标签: python api rest authentication pyramid

我收到了将HTTP身份验证(BasicAuthAuthenticationPolicy)添加到已经实现AuthTktAuthenticationPolicy的Pyramid应用程序的任务...

基本上我需要创建一个RESTful API来验证用户身份(我可以使用BasicAuthAuthenticationPolicy吗?)。

有没有办法检查用户是使用网络界面还是使用api来检查要使用的身份验证政策?

我没有遇到过在单个金字塔应用程序中涵盖两种不同身份验证策略的文档(如果可能的话)。

PS:
我发现了一个博客系列,开始展示如何使用金字塔框架创建RESTful API ... Blogger报告说sersies中将会有6篇文章,但我只能找到其中两篇文章:{ {3}}和Building a RESTful API with Pyramid - Setup。我/他期待着他的上一篇文章:使用金字塔构建RESTful API - 身份验证和ACL,但似乎他不会完成该系列。

回顾我的问题:

  1. 我可以使用Building a RESTful API with Pyramid - Resource and Traversal构建RESTful api来验证用户吗?
  2. 有没有办法检查用户是使用网络界面还是使用API​​ - 检查要使用的身份验证政策?
  3. 任何帮助都会得到赞赏。

3 个答案:

答案 0 :(得分:1)

Pyramid不容易为应用程序的不同部分使用不同的策略(可能需要解决自定义装饰器的问题),但对于多个策略,请查看pyramid_authstack。我将它与Session和BasicAuth策略一起用于与您相同的目的。

答案 1 :(得分:1)

如果一个金字塔应用程序具有两个身份验证策略并不简单,您可以拥有两个单独的Pyramid应用程序,这些应用程序具有不同的策略,每个应用程序组合成一个WSGI堆栈。每个应用程序都可以导入相同的Python代码,因此,基本上,它是使用相同视图和所有内容的两个启动文件。

如果您的应用有不同的网址,您可以使用paste.urlmap进行此操作,如果您的要求更复杂,您甚至可以编写自己的路由器(例如,带有特定HTTP标头的请求会被路由到一个应用程序而无需它到另一个)

答案 2 :(得分:1)

所以我做的是合并了金字塔BasicAuthAuthenticationPolicyCallbackAuthenticationPolicy,最后我得到了this

我修改了callback方法以使用redis会话

要使用此类(HTTPAthentication),您可以执行类似的操作(这是我为我的用例实现它的示例):

def _get_userid(details, request):
    userre = re.compile("""^([a-zA-Z1-9\.]+):([a-zA-Z1-9\.:-]+)$""", re.I)
    userpass = base64.b64decode(details[1])
    res = userre.search(userpass)
    if res:
        return res.group()[0]

def authcheck(username, password, request):
    user = Users.by_username(username, enabled=True)
    host = request.registry.settings.get("authentication.host", "127.0.0.1")
    maxattempts = request.registry.settings.get("authentication.maxattempts",5)
    base = _get_userid(request.authorization, request)
    if request.redis.exists("pimssess:%s" % base64.b64encode(request.remote_addr+":"+base)):
        store = pickle.loads(request.redis.get("pimssess:%s" % base64.b64encode(request.remote_addr+":"+base)))
        if store.get("auth.attempts").get(request.remote_addr):
            if store["auth.attempts"][request.remote_addr] >= maxattempts:
                raise HTTPMethodNotAllowed(body="You have been locked out for 5 minutes")

    if user and user.agent and not user.is_http_auth:
        raise HTTPMethodNotAllowed(body="You are not permitted http access")
    if user and user.agent and user.host != host:
        raise HTTPMethodNotAllowed(body="Your host is not permitted http access")
    if user and user.agent and not user.validate_password(password):
        time.sleep(1.5)
        raise HTTPForbidden(body="Failed login, Incorrect password")
    return getGroups(username)

getGroups函数重新绑定附加到用户的groups列表,即['admin', 'reporting']

我按照这个例子:BasicAuthAuthenticationPolicy(滚动到底部)

对于Web界面登录(CallbackAuthentication),您创建一个登录界面,并创建视图以容纳模板(检查密码和用户名匹配等)

哦,我差点忘了......在你的项目__init__.py中,当你在AuthPolicy中拨打def main(...)时。我做了:

authentication = AuthPolicy(secret='@#^&*$!DSYUIDSA8321789DS',
                        hashalg='sha512', check=authcheck, debug=True)
authorization = ACLAuthorizationPolicy()

config = Configurator(settings=settings, root_factory=RootFactory,
                  authentication_policy=authentication,
                  authorization_policy=authorization)

我希望这可以帮助别人。