minimal auth/security policy implementation

73 views
Skip to first unread message

zsol...@gmail.com

unread,
May 22, 2021, 5:16:34 PM5/22/21
to pylons-discuss
Hi,

I've been using the following auth policies for years, it's been working fine:

    authn_policy = CustomSessionAuthenticationPolicy()
    authz_policy = ACLAuthorizationPolicy()

    config = Configurator(
        settings=settings,
        root_factory=RootFactory,
        authentication_policy=authn_policy,
        authorization_policy=authz_policy,
    )


class RootFactory(object):
    __acl__ = [
        (Allow, Authenticated, 'user'),
        (Allow, 'g:admin', 'admin'),
        (Allow, 'g:superadmin', ALL_PERMISSIONS),
    ]

    def __init__(self, request):
        pass



class CustomSessionAuthenticationPolicy(SessionAuthenticationPolicy):
    def authenticated_userid(self, request):
        return request.user.id

    def effective_principals(self, request):
        principals = [Everyone]
        if request.user:
            principals += [Authenticated]

            if request.user.id == 1:
                principals += ['g:superadmin', 'g:admin']

        return principals

---

I'm trying to migrate off from this, as I simply don't understand what is happening behind and I prefer a much simpler view deriver based approach.

Basically, with a couple of view derivers I could solve all my problems in a few hours, and it also allows me much more flexibility. For example for some views now I can do auth based on API tokens, while most of the views are using session based auth.

My questions is, how can I make the auth/security policies as simple as possible? All I need is working CSRF,  remember and forget.

I'm on 1.10 but I'm happy to migrate to 2.0 if that allows a simplified approach.

So far I was able to get it down to this:

    config = Configurator(
        settings=settings,
        root_factory=RootFactory,
        authentication_policy=SessionAuthenticationPolicy(),
    )

class RootFactory(object):
    __acl__ = [
        (Allow, Authenticated, 'user'),
    ]

    def __init__(self, request):
        pass

Session is via pyramid_session_redis.

Thanks,
Zsolt




Theron Luhn

unread,
May 24, 2021, 2:31:51 PM5/24/21
to pylons-...@googlegroups.com
You may have better luck with the Pyramid 2.0 security system.  It’s much simpler for cases like yours where you don’t need ACL.  For example, your implementation might look like:

class CustomSecurityPolicy:
  def identity(self, request):
    return request.user

  def authenticated_userid(self, request):
    return request.user.id if request.user else None

  def permits(self, request, context, permission):
    if permission == ‘user’ and request.user:
      return Allowed(‘User is signed in.’)
    elif permission == ‘admin’ and request.user and request.user.id == 1:
      return Allowed(‘Admin user is signed in.’)
    else:
      return Denied(‘Access is not allowed.’)

  def remember(request, userid, **kw):
    …  # Same as before

  def forget(request, **kw):
    …

That’s all.  No ACL or root factory, just identity()/authenticated_userid() returning the current user and permits() giving a thumbs up or down if access should be allowed.  Docs:  https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html 
    
View derivers would certainly work.  After all, the security system itself is implemented with a view deriver.  But personally I would avoid circumventing the entire security system like that.

— Theron



--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/60c5a72f-c847-46a9-8e5f-3ed2521f55a1n%40googlegroups.com.

Zsolt Ero

unread,
May 24, 2021, 3:40:05 PM5/24/21
to pylons-...@googlegroups.com
Hi Theron,

Thanks for your reply. It looks indeed simpler. How much more minimal can I make it? I definitely want to "circumvent" the whole security system, I'm perfectly happy with using my new require_admin=True like options.

I just want CSRF to work and it seems to be dependent on RootFactory being defined, which I don't understand. 

Zsolt






You received this message because you are subscribed to a topic in the Google Groups "pylons-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pylons-discuss/7BKhj0G-mbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pylons-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/19F53725-D9C4-4D09-950A-CD92C46CBDCF%40luhn.com.

Michael Merickel

unread,
May 24, 2021, 3:45:45 PM5/24/21
to pylons-...@googlegroups.com
CSRF has nothing to do with authentication other than that you should rotate it at login/logout privilege boundaries at the very least.

You can use the CSRF system without configuring a security/auth policy at all.

- Michael

Theron Luhn

unread,
May 24, 2021, 4:12:30 PM5/24/21
to pylons-...@googlegroups.com
CSRF shouldn’t need a custom root factory or a security policy, the only requirement for the default CSRF (SessionCSRFStoragePolicy) is a session factory.  If you swap it out for CookieCSRFStoragePolicy, you don’t even need that.

— Theron



Reply all
Reply to author
Forward
0 new messages