Alexey_215842
Alexey_215842

Reputation: 11

python django 1.4 how to set two WWW-Authenticate http headers

Im developing small intranet web service. I want authenticate users over kerberos in MS AD or with basic auth. For that reason i need to set two 'WWW-Authenticate' http headers in response 401. How can i do it with Django ?

Should be something like this:

Client: GET www/index.html

Server: HTTP/1.1 401 Unauthorized
        WWW-Authenticate: Negotiate
        WWW-Authenticate: Basic realm="corp site"

This code overwrite header

def auth(request):
    response = None
    auth = request.META.get('HTTP_AUTHORIZATION')
    if not auth:
        response = HttpResponse(status = 401)
        response['WWW-Authenticate'] = 'Negotiate'
        response['WWW-Authenticate'] = 'Basic realm="  trolls place basic auth"'

    elif auth.startswith('Negotiate YII'):
        ...

    return response

Upvotes: 1

Views: 1844

Answers (1)

andrean
andrean

Reputation: 6796

I guess a middleware would be best for this task, but in case you have something else in mind, here is the middleware code adjusted to work with your view(which you can very easily still turn into a middleware if you decide to do so):

from django.conf import settings
from django.http import HttpResponse

def basic_challenge(realm=None):
    if realm is None:
        realm = getattr(settings,
                        'WWW_AUTHENTICATION_REALM',
                        'Restricted Access')
    response = HttpResponse('Authorization Required',
                            mimetype="text/plain")
    response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm)
    response.status_code = 401
    return response

def basic_authenticate(authentication):
    (authmeth, auth) = authentication.split(' ', 1)
    if 'basic' != authmeth.lower():
        return None

    auth = auth.strip().decode('base64')
    username, password = auth.split(':', 1)
    AUTHENTICATION_USERNAME = getattr(settings,
                                      'BASIC_WWW_AUTHENTICATION_USERNAME')
    AUTHENTICATION_PASSWORD = getattr(settings,
                                      'BASIC_WWW_AUTHENTICATION_PASSWORD')
    return (username == AUTHENTICATION_USERNAME and
            password == AUTHENTICATION_PASSWORD)

def auth_view(request):
    auth = request.META.get('HTTP_AUTHORIZATION', '')

    if auth.startswith('Negotiate YII'):
        pass
    elif auth:
        if basic_authenticate(auth):
            #successfully authenticated
            pass
        else:
            return basic_challenge()

    # nothing matched, still return basic challange
    return basic_challenge()

Upvotes: 2

Related Questions