2014-02-14 25 views
2

我正在使用金字塔,並且設置了非常基本的安全/ ACL。我有我想要拒絕訪問的認證用戶(註冊,登錄等),這是很容易的在我的ACL使用這幾個網頁:金字塔安全 - 爲未經身份驗證的用戶添加主體

(Deny, Authenticated, 'guest'), 

的問題是,如果我有這個太,它忽略了後來「拒絕」:

(Allow, Everyone, 'guest'), 

所以我的想法是,添加未經驗證的用戶的主,我可以在勾(看到,因爲有Authenticated,但沒有Unauthenticated

def authenticated(userid, request): 
    if userid == unauthenticated_userid(request): 
     return ['auth:guest'] 

    user = User.get_by_username(userid) 

    if not user: 
     None 

    if user.admin: 
     return ['group:admins', 'group:users'] 

    return ['group:users'] 

問題在於,如果用戶未通過身份驗證(寧願僅給出主體['system.Everyone']並稱之爲一天),AuthTktAuthenticationPolicy圖層看起來不會調用回調函數。

那麼,我在這裏想念什麼,如果有的話?

全部ACL,安全性和配置如下:

class Root(object): 
    __name__ = None 
    __parent__ = None 
    __acl__ = [ 
     (Allow, Everyone, 'view'), 
     (Allow, 'auth:guest', 'guest'), 
     (Deny, Authenticated, 'guest'), 
     (Allow, Authenticated, 'auth'), 
     (Allow, 'group:admins', 'admin'), 
    ] 

    def __init__(self, request): 
     self.request = request 

def main(global_config, **settings): 
    """ This function returns a Pyramid WSGI application. 
    """ 
    engine = engine_from_config(settings, 'sqlalchemy.') 
    DBSession.configure(bind=engine) 

    authn_policy = AuthTktAuthenticationPolicy('devdbcookiesig', 
               callback=authenticated, 
               hashalg='sha512') 
    authz_policy = ACLAuthorizationPolicy() 

    Base.metadata.bind = engine 
    config = Configurator(settings=settings, 
          root_factory=Root) 

    config.set_authentication_policy(authn_policy) 
    config.set_authorization_policy(authz_policy) 

    config.include('pyramid_chameleon') 

    config.add_static_view('static', 'static', cache_max_age=3600) 

    config.set_request_property(get_user, 'user', reify=True) 

    # ... the rest is standard routing 

security.py:

from model.user import User 
from pyramid.security import unauthenticated_userid 

def get_user(request): 
    # the below line is just an example, use your own method of 
    # accessing a database connection here (this could even be another 
    # request property such as request.db, implemented using this same 
    # pattern). 
    userid = unauthenticated_userid(request) 
    if userid is not None: 
     # this should return None if the user doesn't exist 
     # in the database 
     return User.get_by_username(userid) 

def authenticated(userid, request): 
    if userid == unauthenticated_userid(request): 
     return ['auth:guest'] 

    user = User.get_by_username(userid) 

    if not user: 
     None 

    if user.admin: 
     return ['group:admins', 'group:users'] 

    return ['group:users'] 

最後的錯誤:

HTTPForbidden: debug_authorization of url http://localhost/signin (view name u'' against context <devdb.Root object at 0x3dd1f10>): ACLDenied permission 'guest' via ACE '<default deny>' in ACL [('Allow', 'system.Everyone', 'view'), ('Allow', 'auth:guest', 'guest'), ('Deny', 'system.Authenticated', 'guest'), ('Allow', 'system.Authenticated', 'auth'), ('Allow', 'group:admins', 'admin')] on context <devdb.Root object at 0x3dd1f10> for principals ['system.Everyone'] 

回答

4

想通了(種) 。 ACL中的項目順序很重要,因此,如果在放入Allow for everyone之前將Deny用於guest虛擬機進行身份驗證,它就會起作用。

__acl__ = [ 
    (Allow, Everyone, 'view'), 
    (Deny, Authenticated, 'guest'), 
    (Allow, Everyone, 'guest'), 
    (Allow, Authenticated, 'auth'), 
    (Allow, 'group:admins', 'admin'), 
] 

作品而

__acl__ = [ 
    (Allow, Everyone, 'view'), 
    (Allow, Everyone, 'guest'), 
    (Deny, Authenticated, 'guest'), 
    (Allow, Authenticated, 'auth'), 
    (Allow, 'group:admins', 'admin'), 
] 

不(通過驗證的用戶撿「讓大家」又碰上「拒絕認證」前)

仍然不能解決的問題,「爲什麼我不能將自定義的校長添加到未經驗證的用戶「,但它使我得到了我所需要的。

相關問題