Authkit troubles

98 views
Skip to first unread message

Etienne Robillard

unread,
Apr 10, 2014, 10:23:35 AM4/10/14
to pylons-...@googlegroups.com

Hello,

I'm trying to make cookie authentication working with authkit and WSGI but cannot
find a healthy solution. So far here's the code which i'm trying
to use for getting a users object into the environ:

#!/usr/bin/env python
from notmm.controllers.wsgi import WSGIController
from notmm.controllers.auth import LoginController
from notmm.utils.http import httpserver
from notmm.utils.configparse import loadconf

sample_app = WSGIController()
settings = sample_app.settings
global_conf = loadconf('auth.conf')
auth_conf = global_conf['authkit']
auth_app = LoginController(sample_app, auth_conf, settings=settings)

if __name__ == '__main__':
    httpserver.daemonize(auth_app, ('localhost', 8000))


And here's the login view to handle authentication:

def authenticate_user(request, username, password, tokens='', user_data=time.ctime,
    authfunc='paste.auth_tkt.set_user'):
    """Authenticate the user into the site and update the last_modified
    timestamp if authentication and authorization granted user access."""

    try:
        user_setter_func = request.environ[authfunc]
        if valid_password(request.environ, username, password):
            user_setter_func(username, tokens=tokens, user_data=user_data())
            #trigger function here to update the last_modified timestamp
            log.debug('User %s has been authenticated and authorized access!!' % username)
        raise NotAuthenticatedError
    except (KeyError, Exception):
        raise NotAuthenticatedError
    return None

controller:


class AuthCookieController(SessionController):
    """
    Authentication controller to delegate authorization to generic
    user-defined backends.
   
    """

    request_class = HTTPRequest
    response_class = HTTPResponse

    def __init__(self, wsgi_app, auth_conf=None, **kwargs):
           
        super(AuthCookieController, self).__init__(**kwargs)

        #put a pointer on the previous wsgi app in the stack
        self.wsgi_app = wsgi_app

        self.auth_conf_wrapper = auth_middleware(wsgi_app,
            app_conf=auth_conf,
            cookie_secret='secret string',
            #handle_httpexception=False,
            valid=self.authenticate,
            #enforce=self.auth_conf['enforce']
            )
   
    def application(self, environ, start_response, exc_info=None):
        # apply the response middleware wrapper to
        # the WSGI stack and return a callable obj
        return self.auth_conf_wrapper(environ, start_response)


    def authenticate(self, username, password):
        """
        Authenticate with the provided ``username`` and ``password``.
       
        Developers are expected to override this method in custom
        authentication subclasses.
        """

        if username == password:
            return username
        else:
            return None

LoginController = AuthCookieController

the traceback:

> /home/steiner/src/notmm/trunk/examples/auth/views/login.py(33)authenticate_user()
-> if valid_password(request.environ, username, password):
(Pdb) bt
  /home/steiner/src/notmm/trunk/examples/auth/redirect.py(15)<module>()
-> httpserver.daemonize(auth_app, ('localhost', 8000))
  /home/steiner/src/notmm/trunk/lib/notmm/utils/http/httpserver.py(157)daemonize()
-> server.serve()
  /home/steiner/src/notmm/trunk/lib/notmm/utils/http/httpserver.py(115)serve()
-> self.server.serve_forever()
  /usr/local/lib/python2.7/SocketServer.py(238)serve_forever()
-> self._handle_request_noblock()
  /usr/local/lib/python2.7/SocketServer.py(295)_handle_request_noblock()
-> self.process_request(request, client_address)
  /usr/local/lib/python2.7/SocketServer.py(321)process_request()
-> self.finish_request(request, client_address)
  /usr/local/lib/python2.7/SocketServer.py(334)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  /usr/local/lib/python2.7/SocketServer.py(649)__init__()
-> self.handle()
  /usr/local/lib/python2.7/wsgiref/simple_server.py(124)handle()
-> handler.run(self.server.get_app())
  /usr/local/lib/python2.7/wsgiref/handlers.py(85)run()
-> self.result = application(self.environ, self.start_response)
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/base.py(314)__call__()
-> return self.app(environ, start_response)
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/cookie.py(480)__call__()
-> return self.app(environ, cookie_setting_start_response)
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/multi.py(87)__call__()
-> app_iter = app(environ, start_response)
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/multi.py(55)app()
-> return self.default(environ, find)
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/base.py(304)__call__()
-> return self.app(environ, start_response)
  /home/steiner/src/notmm/trunk/examples/auth/views/login.py(96)login()
-> authenticate_user(request, username, password)
> /home/steiner/src/notmm/trunk/examples/auth/views/login.py(33)authenticate_user()
-> if valid_password(request.environ, username, password):
  /home/steiner/src/notmm/trunk/extras/libauthkit/authkit/authenticate/base.py(97)valid_password()
-> raise no_authkit_users_in_environ

And heres the config i use:
[authkit]

authkit.setup.enable = true
authkit.setup.method = redirect,cookie
authkit.setup.handle_exceptions = false

#authkit.authenticate.callback = authkit.authenticate.cookie2:middleware
#authkit.digest.authenticate.user.data = visitor:open_sesame
#authkit.digest.realm = 'Test realm'

# authentication options
authkit.redirect.url = /session_login/
#authkit.user.type = mainapp.accounts.model:UserManager


as you can see authkit middleware doesnt set up a proper users
object, which make authentication fail. Is there thus an alternative method
to set up the middleware to handle form authentication in authkit?

Regards,

Etienne

Mike Orr

unread,
Apr 12, 2014, 11:01:40 AM4/12/14
to pylons-...@googlegroups.com
It has been four years since I've heard anything about AuthKit so I'm
not sure it's still supported. Since you're apparently writing a new
application rather than just keeping an old one running, why are you
using such ancient technologies as AuthKit, middleware, and
(apparently) Pylons? Pyramid has a built-in auth system, more complete
documentation, better support, tweens which are easier to write than
middleware, is forward-compatible with Python 3, and is "Pylons 2".
> --
> 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 post to this group, send email to pylons-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/pylons-discuss.
> For more options, visit https://groups.google.com/d/optout.



--
Mike Orr <slugg...@gmail.com>

Etienne Robillard

unread,
Apr 13, 2014, 8:32:29 AM4/13/14
to pylons-...@googlegroups.com
AuthKit may be "ancient" but  so far i have not found anything decoupled
from a web framework to allow generic authentication in WSGI. Moreover, i wanted to make
a proof of concept with this example to show authkit usability decoupled from Pylons.

Thanks,

Etienne

Bert JW Regeer

unread,
Apr 13, 2014, 11:14:45 AM4/13/14
to pylons-...@googlegroups.com
AuthTkt is still supported, there is a authentication module for it in Pyramid that uses authtkt for auth.

Bert

Mike Orr

unread,
Apr 16, 2014, 1:42:15 PM4/16/14
to pylons-...@googlegroups.com
On Sun, Apr 13, 2014 at 5:32 AM, Etienne Robillard <tka...@yandex.com> wrote:
> AuthKit may be "ancient" but so far i have not found anything decoupled
> from a web framework to allow generic authentication in WSGI.

repoze.who ?

Chris McDonough

unread,
Apr 13, 2014, 11:42:38 AM4/13/14
to pylons-...@googlegroups.com
On 04/13/2014 11:14 AM, Bert JW Regeer wrote:
> AuthTkt is still supported, there is a authentication module for it in Pyramid that uses authtkt for auth.

AuthKit is a package unrelated to authtkt. Etienne wants to use AuthKit
but I don't think anyone on this maillist supports it.

Chris Rossi

unread,
Apr 13, 2014, 11:22:27 AM4/13/14
to pylons-...@googlegroups.com
Note, authkit != authtkt.

Chris

Bert JW Regeer

unread,
Apr 16, 2014, 2:42:20 PM4/16/14
to pylons-...@googlegroups.com
That’s what I get for failing reading comprehension :-).

Never used Authkit.

Bert

Etienne Robillard

unread,
Apr 17, 2014, 8:25:14 AM4/17/14
to pylons-...@googlegroups.com
The reason i want to stick with authkit is that i need to retain
a legacy database backend connection which uses the Schevo database.

The driver itself is looking like this:

from authkit.users import Users

__all__ = ['ManagerBase', 'UserManagerBase']

class ManagerBase(Users):
    """
    Creates a composite proxy object for the User Entity.

    >>> manager = ManagerBase(db.User)
    >>> user = manager.objects.get(username="erob")
    >>> user
    <User account: "Etienne Robillard">
    >>> user.username == "erob"
    True
    """

    # Keep this for compatibility with Pylons ;-)
    api_version = 0.4

    def __init__(self, data, encrypt=None):
        super(ManagerBase, self).__init__(data, encrypt=encrypt)

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'objects'):
            raise AttributeError('%r is missing required objects attribute'%cls)
        new_obj = object.__new__(cls)
        new_obj._default_manager = cls.objects
        return new_obj

class UserManagerBase(ManagerBase):
    def user_exists(self, username):
        #look up the user
        user_object = self.objects.get(username=username)
        if user_object is not None:
            return True
        return False

    def user_has_password(self, username, password):
        u = self.objects.get(username=username)
        if u.f.password.compare(password):
            return True
        return False
   
    ### Roles and Groups permissions
    #def role_exists(self, roles):
    #    # return True if the roles exists
    #    return False

Then in the config, the following key is used to get the user
manager object:

authkit.user.type = mainapp.accounts.model:UserManager

Note that i never until recently managed to get this working elsewhere
than in my initial development site.

Auth_tkt is also included in libauthkit. LibAuthKit is the name for this project
despite slow progresses to decouple the new API into a new package.

Regards,

Etienne

Mike Orr

unread,
Apr 17, 2014, 1:34:49 PM4/17/14
to pylons-...@googlegroups.com
You can try AuthKit's author, James Gardner <ja...@3aims.com>.

I was going to cc this but the problem description has been chopped
off in the replies, so I'll let you write it.

Mike Orr

unread,
Apr 17, 2014, 1:41:59 PM4/17/14
to pylons-...@googlegroups.com
Also, search the pylons-discuss archive for earlier discussions of
AuthKit. They may have something relevant.
--
Mike Orr <slugg...@gmail.com>

Etienne Robillard

unread,
Apr 17, 2014, 5:58:37 PM4/17/14
to pylons-...@googlegroups.com
The author has been contacted but doesn't actively support
issues for AuthKit, so sad :-)

Etienne Robillard

unread,
Apr 19, 2014, 7:04:44 PM4/19/14
to pylons-...@googlegroups.com
I solved partially the issue by properly using the following values in the
development.ini file:

authkit.setup.method = form, cookie
authkit.form.authenticate.user.type = mainapp.accounts.model:UserManager

Note that this affect the login view by replacing the old one with a custom form
which look poor but seem to allow login correctly using auth_tkt (feature) and cookie auth.

Note 2: the old method (redirect) seem broken as a result and returns a looping
302 response code when attempting to access the original login view/form. Not sure how
to solve this.

Regards,

Etienne
Reply all
Reply to author
Forward
0 new messages