Welcome, guest | Sign In | My Account | Store | Cart

Kerberos Single Sign On wsgi middleware

Python, 61 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from base64 import b64decode
import kerberos, commands

class KerberosAuth:
    def __init__(self, wrapped, realm, service='HTTP'):
        self.realm=realm
        self.service=service
        self.wrapped=wrapped

    def __call__(self, environ, start_response):
        def error():
            start_response('500 Error', [
                ('content-type', 'text/plain'),
            ])
            return ['Internal error']
        def noauth():
            start_response('401 Unauthorized', [
                ('content-type', 'text/plain'),
                ('WWW-Authenticate','Negotiate'),
                ('WWW-Authenticate','Basic realm="Secured area"')
            ])
            return ['No auth']


        if 'HTTP_AUTHORIZATION' not in environ:
            return noauth()

        type, authstr = environ['HTTP_AUTHORIZATION'].split(' ', 1)

        if type == 'Negotiate':
            result, context = kerberos.authGSSServerInit(self.service)
            if result != 1:
                return error()

            gssstring=''
            r=kerberos.authGSSServerStep(context,authstr)
            if r == 1:
                gssstring=kerberos.authGSSServerResponse(context)
            else:
                return noauth()
            def new_start_response(status, headers):
                start_response(
                    status,
                    [
                        ('WWW-Authenticate','Negotiate %s' % gssstring)
                    ]+headers
                )

            environ['REMOTE_USER']=kerberos.authGSSServerUserName(context)
            kerberos.authGSSServerClean(context)
        elif type == 'Basic':
            username, password = b64decode(authstr).split(':',1)
            try:
                kerberos.checkPassword(username, password, self.service, self.realm)
            except:
                return noauth()
            new_start_response=start_response
            environ['REMOTE_USER']=username
        return self.wrapped(environ, new_start_response)

application=KerberosAuth(myApplication, 'REALM.MY.DOMAIN.COM')

use at your own risk

1 comment

Alessandro de Manzano 11 years, 2 months ago  # | flag

Very interesting! can someone please show me a real-working example ? I'ld use SPNEGO with ActiveDirectory domains... thanks! Ale