repoze
Turbogears authentication over mongodb users database
Wednesday, March 3rd, 2010 | Software Development | Comments
As we saw that there isn’t a lot of documentation around about how to perform authentication in turbogears over mongodb we decided to create a simple code snippet and public it here to help people trying to obtain the same thing.
This is mainly a proof of concept and is quick and dirty way to obtain it. You will probably have something like ming as your model, instead of directly accessing mongo.
This code also validates password over the clear text one, you will probably have hashed passwords in your database, so remember to change validate_password method as required
To make it work you will have to place this code inside your config.app_cfg, it also expects you to have you database exposed as db inside your model
from my_app.model import db from zope.interface import implements from repoze.who.interfaces import IAuthenticator, IMetadataProvider from repoze.who.plugins.friendlyform import FriendlyFormPlugin from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin from repoze.who.middleware import PluggableAuthenticationMiddleware def validate_password(user, password): return user['password'] == password class MongoAuthenticatorPlugin(object): implements(IAuthenticator) # IAuthenticator def authenticate(self, environ, identity): if not ('login' in identity and 'password' in identity): return None login = identity.get('login') user = db.users.find_one({'user_name':login}) if user and validate_password(user, identity.get('password')): return identity['login'] class MongoUserMDPlugin(object): implements(IMetadataProvider) def add_metadata(self, environ, identity): user_data = {'user_name':identity['repoze.who.userid']} identity['user'] = db.users.find_one(user_data) class MyAppConfig(AppConfig): auth_backend = 'sqlalchemy' #this is a fake, but it's needed to enable #auth middleware at least on TG2.0 login_url = '/login' login_handler = '/login_handler' post_login_url = None logout_handler = '/logout_handler' post_logout_url = None login_counter_name = None def add_auth_middleware(self, app, skip_authentication): cookie_secret = pylons_config.get('auth_cookie_secret', 'myapp_adsfsdfh3423') cookie_name = pylons_config.get('auth_cookie_name', 'myapp_auth') who_args = {} form_plugin = FriendlyFormPlugin(self.login_url, self.login_handler, self.post_login_url, self.logout_handler, self.post_logout_url, login_counter_name=self.login_counter_name, rememberer_name='cookie') challengers = [('form', form_plugin)] auth = MongoAuthenticatorPlugin() authenticators = [('mongoauth', auth)] cookie = AuthTktCookiePlugin(cookie_secret, cookie_name) identifiers = [('cookie', cookie), ('form', form_plugin)] provider = MongoUserMDPlugin() mdproviders = [('mongoprovider', provider)] from repoze.who.classifiers import default_request_classifier from repoze.who.classifiers import default_challenge_decider log_stream = None app = PluggableAuthenticationMiddleware(app, identifiers, authenticators, challengers, mdproviders, default_request_classifier, default_challenge_decider) return app base_config = MyAppConfig() base_config.renderers = [] base_config.package = my_app #Set the default renderer base_config.default_renderer = 'genshi' base_config.renderers.append('genshi') base_config.renderers.append('json') #Configure the base SQLALchemy Setup base_config.use_sqlalchemy = False base_config.model = my_app.model