Login / Authorisation mit Werkzeug, FastCGI

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
bake
User
Beiträge: 29
Registriert: Dienstag 20. November 2007, 08:12
Wohnort: Hamburg

Hi,
ich arbeite derzeit mit Werkzeug und FastCGI und möchte nun, dass der Benutzer sich einloggen muss, bevor er die eigentlichen Webseite(n) sieht.
Bietet Werkzeug Bordmittel um ein Login zu realisieren? Habe mir die Authorization Class angeguckt, werde aber nicht ganz schlau wie ich das ganze realisiere... Gibt es irgendwo eine Beispielimplementierung die ich mir anschauen kann um das ganze zu verstehen? Weiter unten die dispatch funktion aus der wsgiapp.py (falls für die Antwort benötigt):

Code: Alles auswählen

def dispatch(self, environ, start_response):
    local.application = self
    request = Request(environ)
    local.url_adapter = adapter = url_map.bind_to_environ(environ)
    try:
        endpoint, values = adapter.match()
        handler = getattr(views, endpoint)
        response = handler(request, **values)
    except NotFound, e:
        response = views.not_found(request)
        response.status_code = 404
    except HTTPException, e:
        response = e
    return ClosingIterator(response(environ, start_response),
                               [local_manager.cleanup])

[i]who we are is but a stepping stone to
what we can become...[/i]
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Suchst du das hier?
Benutzeravatar
bake
User
Beiträge: 29
Registriert: Dienstag 20. November 2007, 08:12
Wohnort: Hamburg

Öhm ja... Oh Gott... Tomaten auf den Augen und so... :oops: Vielen Dank!
[i]who we are is but a stepping stone to
what we can become...[/i]
lunar

Alternativ kannst du auch authkit verwenden. Das unterstützt alle möglichen Authentifizierungsverfahren, und lässt sich als WSGI-Middleware in jede WSGI-Anwendung einbinden. Außerdem bietet es eine API zum Verwalten von Nutzern, Gruppen und Rollen.

Für einfache Anwendungen ist das sicherlich Overkill, aber wenn's größer werden soll, spart man sich ein wenig Arbeit.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Die Wahl bzw. Nutzung einer WSGI-Middleware hängt natürlich davon ab, inwieweit du evtl. bereits vorhandene Benutzerstrukturen und -mechanismen mit dem Login verheiraten willst.
Benutzeravatar
bake
User
Beiträge: 29
Registriert: Dienstag 20. November 2007, 08:12
Wohnort: Hamburg

Nun habe ich endlich Zeit gefunden mich mit der Authentifizierung zu beschäftigen. Habe versucht, dass httpbasicauth example von pocoo zum laufen zu bringen, irgendwie scheiter ich...
Er fragt zwar den Username und das Password ab, leitet mich aber nach der Eingabe nicht weiter, sondern fragt sofort wieder nach einem user und password ...

Code: Alles auswählen

class YouConduct(object):

    def __init__(self):
        local.application = self
        self.users = {'user1': 'password1', 'user2': 'password2'}
        self.realm = 'login required'
        
        self.dispatch = SharedDataMiddleware(self.dispatch, {
            '/shared':  SHARED_PATH,
            '/memberportraits': MEMBERPORTRAITS_PATH
        })

    def check_auth(self, username, password):
        return username in self.users and self.users[username] == password
    
    def auth_required(self, request):
        return Response('Could not verify your access level for that URL.\n'
                        'You have to login with proper credentials', 401,
                        {'WWW-Authenticate': 'Basic realm="%s"' % self.realm})

    def dispatch(self, environ, start_response):
        local.url_adapter = adapter = url_map.bind_to_environ(environ)
        try:
            endpoint, values = adapter.match()
            handler = getattr(views, endpoint)
            response = handler(request, **values)
        except NotFound, e:
            response = views.not_found(request)
            response.status_code = 404
        except HTTPException, e:
            response = e
        return ClosingIterator(response(environ, start_response),
                               [local_manager.cleanup])

    def __call__(self, environ, start_response):
        local.application = self
        request = Request(environ)
        auth = request.authorization
        if not auth or not self.check_auth(auth.username, auth.password):
            response = self.auth_required(request)
            return response(environ, start_response)
        else:
            return self.dispatch(environ, start_response)
[i]who we are is but a stepping stone to
what we can become...[/i]
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Ich verwende barrel für Authentifikation mit werkzeug. Das funktioniert gut.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
lunar

Nutz doch mal das logging-Modul und lass dir die Parameter für die einzelnen Funktionen und die Header des Requests ausgeben. Dann dürftest du recht schnell sehen, wo es hakt.

Im Übrigen hat Werkzeug auch ein Mixin, um dem Authenticate-Header komfortabel anzusprechen, das musst du nicht selber tun.
OverNord
User
Beiträge: 72
Registriert: Donnerstag 24. Januar 2008, 11:59
Kontaktdaten:

Ich habe mal etwas mit dem httpbasicauth example von pocoo rumgespielt, was auf dem Developmentserver auch gut funktionierte, als ich das ganze dann mal auf meinem Apache getestet habe, war Request.authorization = None, weiß jemand warum das so ist?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo!

Irgendwer hat hier im Forum mal geschrieben, dass Authentifizierung NICHT über FastCGI und CGI funktioniert. Wenn du also Authentifizierung hinter einem Apachen haben möchtest, dann kannst du die Apache-Authentifizierung verwenden.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lunar

Wenn du flup als WSGI-Gateway nutzt, dann ist die Ursache ein Fehler in flup. Es gibt den entsprechenden Header nicht – wie von WSGI verlangt – als "HTTP_AUTHORIZATION" weiter, sondern als "Authorization". Die Lösung ist eine Middleware, die die Schlüssel im environ-Mapping gerade biegt.

Ausführlich steht das im Werkzeug-Wiki.

@gerold
Es funktioniert, nur eben nicht ohne Hack.
OverNord
User
Beiträge: 72
Registriert: Donnerstag 24. Januar 2008, 11:59
Kontaktdaten:

Ich nutze mod_wsgi.
lunar

Hast du mod_wsgi auch so konfiguriert, dass es die Header durchreicht? Wenn ja, probiere doch mal die Middleware im Wiki-Artikel aus und schreibe mal das "environ"-Mapping mit einer vorgeschalteten Middleware ins Log, um zu schauen, ob der Header überhaupt ankommt, oder ob er nur im falschen Schlüssel steht.
OverNord
User
Beiträge: 72
Registriert: Donnerstag 24. Januar 2008, 11:59
Kontaktdaten:

So, hab das Problem behoben, musste nur WSGIPassAuthorization auf on setzen. Danke, für die Hilfe.
Antworten