On Apr 11, 9:45 am, Graham Dumpleton <[email protected]> wrote: > On 11 April 2010 05:16, Vishwajeet <[email protected]> wrote: > > > > > > > I don't think I have anything like that and I am sure that request is > > not going to django. > > The configuration which I have is something as shown below > > > <Directory "/setup/trunk/sspl/src/ssplsite/data/dav/test"> > > > DAV on > > AuthType Basic > > AuthName "WebDAV Authentication" > > AuthBasicProvider wsgi > > WSGIAuthUserScript /setup/trunk/sspl/src/ssplsite/data/ > > repos/svn_wsgi.py application-group=webdav > > WSGIAuthGroupScript /setup/trunk/sspl/src/ssplsite/ > > data/repos/svn_wsgi.py application-group=webdav > > Require group allowed > > #Require valid-user > > Not that it will necessarily make a difference, you still need the > 'Require valid-user' line. I had required valid-user but commented it while experimenting, you are right it does not makes any difference. > > BTW, it is 'mod_authz_default' that returns HTTP_UNAUTHORIZED. It > seems that returning 401 is the correct thing to do as you want to > give the user the option of entering different user credentials. If > you return HTTP_FORBIDDEN then the browser will remember the user > credentials and you will not get an option to change them as there is > no concept of logout for Basic authentication. If you say so, it will > even remember the credentials across browser restarts, so restarting > browser doesn't help. I should have remembered this before when > thought that forbidden should be returned, has to be unauthorized. I am not sure about this but Subversion also uses basic auth and returns forbidden in case you enter right credentials and do not have access. Browser restart does clear the Basic authentication as far as I have seen, I still feel it should give 403 otherwise user will not know whether his credentials are wrong or he does not have access to resource.
> > Graham > > > AllowOverride None > > Order allow,deny > > Allow from all > > > </Directory> > > If group allowed is returned all seems to work well but in case of > > some other group it keeps on prompting for username password, I tried > > it in location block as well. > > > On Apr 10, 3:59 pm, Graham Dumpleton <[email protected]> > > wrote: > >> On 10 April 2010 04:33, Vishwajeet <[email protected]> wrote: > > >> > On Apr 9, 6:00 pm, Graham Dumpleton <[email protected]> > >> > wrote: > >> >> On 9 April 2010 22:23, Graham Dumpleton <[email protected]> > >> >> wrote: > > >> >> > On 9 April 2010 22:19, Vishwajeet <[email protected]> wrote: > > >> >> >> On Apr 9, 3:32 pm, Graham Dumpleton <[email protected]> > >> >> >> wrote: > >> >> >>> On 9 April 2010 19:00, vishwajeet singh <[email protected]> > >> >> >>> wrote: > > >> >> >>> > Thanks for the quck response Graham I have gone through these > >> >> >>> > links many > >> >> >>> > times but still fail to understand how it will work for me. > >> >> >>> > Let me give you some more details > >> >> >>> > I am not doing either group authorization or host authorization, > >> >> >>> > I have > >> >> >>> > django app and users have different roles in that application, so > >> >> >>> > once user > >> >> >>> > is authenticated I want to look into db if the user is in > >> >> >>> > particular role or > >> >> >>> > not, if he is not a role give him authorization required or you > >> >> >>> > don't have > >> >> >>> > access to this resource. I want to use this authorization to > >> >> >>> > handle access > >> >> >>> > for webdav folders which are not directly part of django app. > >> >> >>> > Hope that makes me more clear, thank you so much for your > >> >> >>> > response. > > >> >> >>> Depends on how you are going to do this with Django, but a role is > >> >> >>> not > >> >> >>> really any different to a group or even a Django user permission. > > >> >> >>> For example, the following might be able to be used (although I have > >> >> >>> not tested it). > > >> >> >>> import os, sys > >> >> >>> sys.path.append('/usr/local/django') > >> >> >>> os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' > > >> >> >>> from django.contrib.auth.models import User > >> >> >>> from django import db > > >> >> >>> def groups_for_user(environ, user): > >> >> >>> db.reset_queries() > > >> >> >>> kwargs = {'username': user, 'is_active': True} > > >> >> >>> try: > >> >> >>> try: > >> >> >>> user = User.objects.get(**kwargs) > >> >> >>> except User.DoesNotExist: > >> >> >>> return [''] > > >> >> >>> return user.get_group_permissions() > >> >> >>> finally: > >> >> >>> db.connection.close() > > >> >> >>> In other words, just look up user and return permissions associated > >> >> >>> with that user through the groups they are in. > > >> >> >>> I don't actually use Django but I presume this can be used to > >> >> >>> designate the roles they have. > > >> >> >>> Then in Apache configuration you can have: > > >> >> >>> AuthType Basic > >> >> >>> AuthName "Top Secret" > >> >> >>> AuthBasicProvider dbm > >> >> >>> AuthDBMUserFile /usr/local/wsgi/accounts.dbm > >> >> >>> WSGIAuthGroupScript /usr/local/wsgi/scripts/auth.wsgi > >> >> >>> Require valid-user > > >> >> >>> <Location /some/url> > >> >> >>> Require group can_do_stuff > >> >> >>> </Location> > > >> >> >>> <Location /some/other/url> > >> >> >>> Require group can_do_other_stuff > >> >> >>> </Location> > > >> >> >>> So don't get hung up on the 'group' name used as argument to > >> >> >>> 'Require' > >> >> >>> directive. You can still return a list of permissions and match > >> >> >>> against that. > > >> >> >>> From Apache 2.3 onwards, you will have to actually use 'wsgi-group' > >> >> >>> instead of 'group'. Seems I haven't noted this in documentation and > >> >> >>> that 'wsgi-group' already works for older Apache and should now be > >> >> >>> used in preference to 'group'. > > >> >> >>> Also note if using check_password() to authenticate user against > >> >> >>> Django previously, to avoid second database lookup, you could always > >> >> >>> stash the permissions in thread local storage and have the > >> >> >>> groups_for_user() look up that, validate is for same user and return > >> >> >>> it. > > >> >> >>> You will need to use mod_wsgi 3.X to use thread local storage like > >> >> >>> that however. > > >> >> >>> BTW, if you get this working, post what you use. If I get a working > >> >> >>> example from someone with a bit of a description of what you do on > >> >> >>> Django admin side to populate permissions, could include it in > >> >> >>> documentation as example. > > >> >> >> Thanks for an elaborate reply that really helped me to move in the > >> >> >> right direction, I did the suggested changes and It seems to be > >> >> >> working. > >> >> >> though I need to do some more testing before I have something > >> >> >> concrete :) > > >> >> >>> Also note if using check_password() to authenticate user against > >> >> >>> Django previously, to avoid second database lookup, you could always > >> >> >>> stash the permissions in thread local storage and have the > >> >> >>> groups_for_user() look up that, validate is for same user and return > >> >> >>> it. > >> >> >> I am using check_password() but I don't know how to stash the > >> >> >> permissions in thread local storage, can you please let me know how > >> >> >> to > >> >> >> do this ? > > >> >> > Will have to be tomorrow, no time tonight now and am logging off. > > >> >> Have couple of minutes left. Use something like: > > >> >> import os, sys > >> >> sys.path.append('/usr/local/django') > >> >> os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' > > >> >> from django.contrib.auth.models import User > >> >> from django import db > > >> >> import threading > > >> >> cache = threading.local() > > >> >> def check_password(environ, username, password): > > >> >> cache.username = None > >> >> cache.permissions = [''] > > >> >> db.reset_queries() > > >> >> kwargs = {'username': username, 'is_active': True} > > >> >> try: > >> >> try: > >> >> user = User.objects.get(**kwargs) > >> >> except User.DoesNotExist: > >> >> return None > > >> >> if user.check_password(password): > >> >> cache.username = username > >> >> cache.permissions = user.get_group_permissions() > >> >> return True > >> >> else: > >> >> return False > >> >> finally: > >> >> db.connection.close() > > >> >> def groups_for_user(environ, username): > >> >> if not cache.username or cache.username != username: > >> >> cache.username = None > >> >> cache.permissions = [''] > >> >> return [''] > > >> >> permissions = cache.permissions > >> >> cache.username = None > >> >> cache.permissions = [''] > >> >> return permissions > > >> >> Have to do this as only easy way of passing information between the > >> >> two Apache phases as no easy way of stashing information back in > >> >> Apache request object for passing across. > > >> >> Note that by WSGIAuthUserScript and WSGIAuthGroupScript must be > >> >> delegated to same application-group for this to work as thread locals > >> >> are specific to an interpreter. > > >> > Thanks I got it working > > >> >> >> One more thing is that if the required group is not matched it keeps > >> >> >> on prompting for authentication instead of saying authorization > >> >> >> required. > > >> > But this problem is still bugging me not able to understand why Apache > >> > keeps on returning 401 instead of 403 if some other group is returned > >> > instead of desired one. > > >> Do you have an explicitly ErrorDocument directive specificied for 403 > >> to map error handler to a URL. > > >> If not explicitly done by you, have you got multi lang error pages in > >> Apache enabled. Ie. > > >> # Multi-language error messages > >> Include /private/etc/apache2/extra/httpd-multilang-errordoc.conf > > >> If you have these enabled, it could be redirecting 403 to an error URL > >> which is getting passed through to Django application, but Django > >> doesn't have that URL mapped and returns 401. > > >> If this happens, I would actually have expected the end result to be a > >> 500 error though as Apache would treat a 401 for error document to be > >> an internal server error. > > >> Graham > > >> >> Graham > > >> >> >> One more thing is that if the required group is not matched it keeps > >> >> >> on prompting for authentication instead of saying > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "modwsgi" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/modwsgi?hl=en.
