plugable authentication

28 views
Skip to first unread message

Eric Lemoine

unread,
May 28, 2012, 5:28:06 AM5/28/12
to pylons-...@googlegroups.com
Hi

My Pyramid-based framework includes a “login” view that looks like this:

def login(request):
    username = request.params.get('username')
    password = request.params.get('password')
    if username is None or password is None:
        return HTTPBadRequest(...)
    user = Session.query(User).filter_by(username=username).first()
    user_is_valid = user and user.validate_password(password)
    if user_is_valid:
        headers = remember(request, username)
        return HTTPFound(location=request.params.get('come_from'), headers=headers)
    return HTTPUnauthorized(...)

So this login action gets the user from a “user” database table, and validates the password by calling “validate_password” on the “user” (SQLAlchemy) object. The action also takes care of returning an appropriate HTTP response, based on the received HTTP params and whether the user can be authenticated or not.

I'd like the make the authentication/password validation process configurable. Applications based on my framework should be able to register their own authentication/password validation process. And I'd like to know what's the best way to achieve that.

The application could overwrite the “login” view completely. But the “login” view includes logic that I think should not be duplicated.

So I'd rather put the code

     user = Session.query(User).filter_by(username=username).first()
    user_is_valid = user and user.validate_password(password)

in a “default” function, and make it possible for applications to overwrite this function.

I've been thinking about adding a configurator directive (with add_directive) for that, like “set_user_authenticator” or something. But I'm wondering if this is an appropriate solution, or it there are more Pyramid standard ways for that.

Any guidance welcome.

Thanks,


--
Eric Lemoine

Camptocamp France SAS
Savoie Technolac, BP 352
73377 Le Bourget du Lac, Cedex

Tel : 00 33 4 79 44 44 96
Mail : eric.l...@camptocamp.com
http://www.camptocamp.com

Robert Forkel

unread,
May 28, 2012, 6:43:21 AM5/28/12
to pylons-...@googlegroups.com
The configurator directive sounds like a reasonable approach to me. As
soon as you find yourself registering more configurable functions,
using the underlying zope component registry [1] methods directly
might be easier [2].
But this would mean you're relying on what seems to be considered an
implementation detail of pyramid.
In case of authentication, though, you might just want to look at
repoze.who which you can use via pyramid_who [3].
regards,
robert

[1] http://docs.pylonsproject.org/projects/pyramid/en/latest/api/registry.html
[2] http://www.muthukadan.net/docs/zca.html#registerutility
[3] http://pypi.python.org/pypi/pyramid_who/0.3
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To post to this group, send email to pylons-...@googlegroups.com.
> To unsubscribe from this group, send email to
> pylons-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.

Jonathan Vanasco

unread,
May 28, 2012, 4:41:58 PM5/28/12
to pylons-discuss
One of my companies built a framework based on a similar concept a
while back on Pylons, and deployed around a dozen apps on it for
ourselves and our clients.

It was really neat to get things off the ground, and quickly became a
pain-in-the-ass as projects went through agile iterations --
everything started to depart drastically within the database ,
application, and caching/server structure. We ended up doing 10x more
work to keep everything compatible - which ultimately defeated the
entire purpose.

If I were to do it again, I'd do this:

- focus on making the is_logged_in validation ( setting , unsetting ,
persisting , integration with other frameworks like repoze , etc )

- just template out the login/logout logic into a scaffold or 'copy-
paste' , and have it call the framework stuff that sets/unsets/checks
the logged_in status.

That might not be compatible with your goals, but if I had to do
things all over again -- that's what I'd do.
Reply all
Reply to author
Forward
0 new messages