【问题标题】:pyramid security authenticating request金字塔安全认证请求
【发布时间】:2021-03-21 08:49:39
【问题描述】:

我正在使用金字塔身份验证,下面是我的以下代码,用于记住请求并查看同一用户是否已通过身份验证。

from pyramid.view import forbidden_view_config
from pyramid.response import Response
from pyramid.httpexceptions import HTTPFound, HTTPSeeOther
from pyramid.security import NO_PERMISSION_REQUIRED, Everyone, remember, authenticated_userid, unauthenticated_userid

from .oauth import OAuth
from .utils import redirect_path
from pyramid.view import (
    view_config,

    )
import requests
import logging
import json

log = logging.getLogger(__name__)

@view_config(route_name='login')
def login(request):

    print('login **** start')

    sm_user = request.headers.get('sm_user')
    userid = request.cookies.get('userid')

    print('sm_user - {0}'.format(sm_user))
    print('userid - {0}'.format(userid))

    if not sm_user and not userid:
        return HTTPFound(request.route_url('callback'))

    login_url = request.route_url('login')

    redirect_to = redirect_path(request)

    response = Response(json.dumps({'note': 'testing'}))
    return response


@view_config(route_name='callback')
def callback(request):

    log.debug('********* callback **********')
    print_requests(request)

    code = request.params.get('code')

    # userid, name = OAuth(code).get_user_info()
    userid ='lak'
    name = 'test'
    headers = remember(request, userid)
    login_url = request.route_url('login')
    print('login_url - ', login_url)

    response = HTTPSeeOther(location=login_url, headers=headers)
    response.set_cookie('name', name)
    response.set_cookie('userid', userid)

    return response


# @view_config(route_name='resource_1', permission='edit')
@view_config(route_name='resource_1')
def resource_1(request):
    print('u - ',unauthenticated_userid(request))
    print('a -', authenticated_userid(request))
    r = {'test': 'resource_1'}
    return Response(json.dumps(r))


@forbidden_view_config()
def resource_2(request):
    return Response('You are not allowed', status='403 Forbidden')

@view_config(route_name='mashup')
def mashup(request):
    print('mashup')

    r = {'Note': 'Undergoing test'}

    return Response(json.dumps(r))


def print_requests(request):
    pass

main.py

from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.config import Configurator
from .security import groupfinder


def main(global_config, **settings):
    config = Configurator(settings=settings,
                          root_factory='.resources.Root')
    config.include('pyramid_chameleon')

    # Security policies
    authn_policy = AuthTktAuthenticationPolicy(
        settings['tutorial.secret'], callback=groupfinder,
        hashalg='sha512')
    authz_policy = ACLAuthorizationPolicy()
    config.set_authentication_policy(authn_policy)
    config.set_authorization_policy(authz_policy)

    config.add_route('login', '/')
    config.add_route('callback', '/login/oauth2/code')
    config.add_route('resource_1', '/resource_1')
    config.add_route('resource_2', '/resource_2')
    config.add_route('mashup', '/mashup.html')

    config.scan('.views')
    return config.make_wsgi_app()

security.py

import bcrypt


def hash_password(pw):
    pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt())
    return pwhash.decode('utf8')

def check_password(pw, hashed_pw):
    expected_hash = hashed_pw.encode('utf8')
    return bcrypt.checkpw(pw.encode('utf8'), expected_hash)


USERS = {'editor': hash_password('editor'),
         'viewer': hash_password('viewer')}
GROUPS = {'editor': ['group:editors'],
          'lak': ['group:editors']}


def groupfinder(userid, request):
    print('******** groupfinder ****', userid)
    print('group - ', GROUPS.get(userid, []))
    if userid in USERS:
        return GROUPS.get(userid, [])
            

resources.py

from pyramid.security import Allow, Everyone


class Root(object):
    __acl__ = [(Allow, Everyone, 'view'),
               (Allow, 'group:editors', 'edit')]

    def __init__(self, request):
        pass

Github 网址:-

https://github.com/PREM1980/spa_authentication

【问题讨论】:

  • 等等,您是否希望 authenticated_userid 在同一个请求中返回某些内容?通常用户使用登录名和密码提交(未经身份验证的)请求,服务器返回一些标头(Set-Cookie);然后浏览器在后续请求中发送一些 cookie;然后服务器会看到 cookie,并且 authenticated_userid 会返回一些东西。不在同一个请求-响应周期内。
  • 您的问题是什么?你观察到了什么?你期望会发生什么?我建议看看tutorial for authentication step 的一个很好的例子。
  • 提供了下面的cmets..我知道应该在下一个周期调用经过身份验证的请求,但不确定为什么没有调用回调函数。
  • 您的登录视图功能如何以及您的其他视图功能如何查看用户应该进行身份验证的位置?前者应该返回一些响应,而后者应该受到许可的保护。请编辑问题以包含视图函数声明。
  • 我已添加信息。当用户登录时,他被重定向到一个 OAUTH 页面,一旦他同意,我得到用户信息并调用记住功能。我希望再次调用登录页面时触发回调。

标签: python pyramid


【解决方案1】:

默认情况下,authenticated_userid 不会在您调用 remember 的同一请求中更改。它只是在响应对象上设置一个cookie,客户端将在指示身份验证状态的NEXT请求中返回该cookie。在当前请求中,如果您希望 authenticated_userid 更改其值,那么您将必须实现自己的 remember 或其他管理它的机制 - Pyramid 默认情况下不会在其任何身份验证策略中执行此操作。身份验证策略 API 很简单,如果您觉得需要更改其工作方式,可以对其进行子类化/覆盖。

【讨论】:

  • 在 route-resource_1 中调用的 authenticated_userid 显示没有,即使我访问了登录页面以记住用户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 2020-01-15
  • 2017-12-20
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
相关资源
最近更新 更多