金字塔中使用http头的身份验证

2024-05-03 20:45:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在寻找一种方法来逐个用户验证http头中传递的密码。在

curl --user user1:pass1 http://localhost:6543/the_resource

这样做的目的是检查传递的凭证是否允许用户查看*该资源*如果不允许,则返回401-禁止。在

{a1}和登录策略的例子,我只知道如何绑定一个登录金字塔视图。在

我将感谢任何帮助,如何开始。在

我又想起了一件事。如何强制此pup-up登录窗口进行基本身份验证?在


Tags: the方法用户目的localhosthttp密码a1
2条回答

最终,如何使用身份验证和授权变得清晰起来。所有的东西都写出来了,只是我没有马上领会到这个概念。我会试着写下我是如何让它工作的,用一种愚蠢的方式来解释,这是我不得不自己解释的。我希望这对某人有用。所有的资料来源都可以帮助我理解。如果我做错了什么,请纠正我。在

身份验证

最重要的是basic authentication,其中BasicAuthenticationPolicy必须具有可以在以后金字塔应用程序中使用的方法,例如经过身份验证的用户标识(request)。这些方法使用_get_basicauth_credentials()来提取在http头中传递的登录名和密码。实际的登录名和密码是否正确的检查发生在mycheck()中。在

现在,在\uu init_uu.py中,我们必须将方法mycheck作为参数的BasicAuthenticationPolicy添加到我们的应用程序配置器中,这样金字塔就可以使用它了。在

在认证问题上就这样。现在,您应该能够使用authenticated_userid(request)验证if和who(请参见视图.py)

授权

要对资源使用金字塔式授权,我们需要将ACLAuthorizationPolicy添加到配置器中的优init_uu.py中,并向资源中添加uUuACL。在最简单的情况下,根工厂(请参见thisthis)ACL定义了哪个组拥有什么权限。如果我没弄错的话组:查看器'视图''组:查看器'必须是身份验证方法mycheck()返回的。在

授权的最后一步是使用decorator(或add_route)向特定视图添加权限。如果我们将ACL权限-view-添加到视图页面,那么查看者组:是允许查看该页面(调用查看页面)。在

基本_认证.py在

import binascii

from zope.interface import implements

from paste.httpheaders import AUTHORIZATION
from paste.httpheaders import WWW_AUTHENTICATE

from pyramid.interfaces import IAuthenticationPolicy
from pyramid.security import Everyone
from pyramid.security import Authenticated
import yaml

def mycheck(credentials, request):
    login = credentials['login']
    password = credentials['password']

    USERS = {'user1':'pass1',
             'user2':'pass2'}
    GROUPS = {'user1':['group:viewers'],
              'user2':['group:editors']}

    if login in USERS and USERS[login] == password:
        return GROUPS.get(login, [])
    else:
        return None


def _get_basicauth_credentials(request):
    authorization = AUTHORIZATION(request.environ)
    try:
        authmeth, auth = authorization.split(' ', 1)
    except ValueError: # not enough values to unpack
        return None
    if authmeth.lower() == 'basic':
        try:
            auth = auth.strip().decode('base64')
        except binascii.Error: # can't decode
            return None
        try:
            login, password = auth.split(':', 1)
        except ValueError: # not enough values to unpack
            return None
        return {'login':login, 'password':password}

    return None

class BasicAuthenticationPolicy(object):
    """ A :app:`Pyramid` :term:`authentication policy` which
    obtains data from basic authentication headers.

    Constructor Arguments

    ``check``

        A callback passed the credentials and the request,
        expected to return None if the userid doesn't exist or a sequence
        of group identifiers (possibly empty) if the user does exist.
        Required.

    ``realm``

        Default: ``Realm``.  The Basic Auth realm string.

    """
    implements(IAuthenticationPolicy)

    def __init__(self, check, realm='Realm'):
        self.check = check
        self.realm = realm

    def authenticated_userid(self, request):
        credentials = _get_basicauth_credentials(request)
        if credentials is None:
            return None
        userid = credentials['login']
        if self.check(credentials, request) is not None: # is not None!
            return userid

    def effective_principals(self, request):
        effective_principals = [Everyone]
        credentials = _get_basicauth_credentials(request)
        if credentials is None:
            return effective_principals
        userid = credentials['login']
        groups = self.check(credentials, request)
        if groups is None: # is None!
            return effective_principals
        effective_principals.append(Authenticated)
        effective_principals.append(userid)
        effective_principals.extend(groups)
        return effective_principals

    def unauthenticated_userid(self, request):
        creds = self._get_credentials(request)
        if creds is not None:
            return creds['login']
        return None

    def remember(self, request, principal, **kw):
        return []

    def forget(self, request):
        head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
        return head

我的项目

^{pr2}$

在模型.py在

from pyramid.security import Allow

class RootFactory(object):
    __acl__ = [ (Allow, 'group:viewers', 'view'),
                (Allow, 'group:editors', 'edit') ]
    def __init__(self, request):
        pass

在视图.py在

from pyramid.security import authenticated_userid
from pyramid.view import view_config


#def my_view(request):
#    return render_to_response('templates/simple.pt', {})

@view_config(route_name='view_page', renderer='templates/view.pt', permission='view')
def view_page(request):
    return {}

@view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit')
def edit_page(request):
    return {}    

你要的是基本认证。你链接到你想要使用的配方。它处理识别用户并计算其主体。ACL系统使用主体以及在视图上指定的权限来确定允许/拒绝访问。在

我认为诀窍在于找出如何处理拒绝用户访问资源的问题,而这一点在配方中没有列举。您可以通过提供一个自定义的“禁止的视图”来实现这一点,当该视图拒绝访问时,该视图将被调用。此时,Basic声明您向客户提供了一个挑战。在

@forbidden_view_config()
def forbidden_view(request):
    resp = HTTPUnauthorized()
    resp.www_authenticate = 'Basic realm="Secure Area"'
    return resp

这是未经测试的,但可以让你大致了解如何使用禁止的视图。这将挑战客户机,然后他们可以自由地发出另一个请求(希望是使用凭据),该请求将转换为映射到您关心的权限的主体。在

相关问题 更多 >