Twisted Authentication with Perspective Broker
Has been studying Tvisted week, read the book and most of the docks, but I can not understand a single moment. From Twisted docs http://twistedmatrix.com/documents/10.1.0/core/howto/pb-cred.html server
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from zope.interface import implements
from twisted.spread import pb
from twisted.cred import checkers, portal
from twisted.internet import reactor
class MyPerspective(pb.Avatar):
def __init__(self, name):
self.name = name
def perspective_foo(self, arg):
print "I am", self.name, "perspective_foo(",arg,") called on", self
class MyRealm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if pb.IPerspective not in interfaces:
raise NotImplementedError
return pb.IPerspective, MyPerspective(avatarId), lambda:None
p = portal.Portal(MyRealm())
c = checkers.InMemoryUsernamePasswordDatabaseDontUse(user1="pass1",
user2="pass2")
p.registerChecker(c)
reactor.listenTCP(8800, pb.PBServerFactory(p))
reactor.run()
client
#!/usr/bin/env python
# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.spread import pb
from twisted.internet import reactor
from twisted.cred import credentials
def main():
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8800, factory)
def1 = factory.login(credentials.UsernamePassword("user1", "pass1"))
def1.addCallback(connected)
reactor.run()
def connected(perspective):
print "got perspective1 ref:", perspective
print "asking it to foo(13)"
perspective.callRemote("foo", 13)
main()
if the user enters the wrong password:
Unhandled Error
Traceback (most recent call last):
Failure: twisted.cred.e开发者_如何学JAVArror.UnauthorizedLogin:
I instead of an exception, tell the user that he does not put the correct password?\bad username
I tried to change:
c = checkers.InMemoryUsernamePasswordDatabaseDontUse(user1="pass1",user2="pass2")
p.registerChecker(c)
on
passwords = {
'admin': 'aaa',
'user1': 'bbb',
'user2': 'ccc'
}
p.registerChecker(PasswordDictChecker(passwords))
class PasswordDictChecker(object):
implements(checkers.ICredentialsChecker)
credentialInterfaces = (credentials.IUsernamePassword,)
def __init__(self, passwords):
"passwords: a dict-like object mapping usernames to passwords"
self.passwords = passwords
def requestAvatarId(self, credentials):
username = credentials.username
if self.passwords.has_key(username):
if credentials.password == self.passwords[username]:
return defer.succeed(username)
else:
return defer.fail(
credError.UnauthorizedLogin("Bad password"))
else:
return defer.fail(
credError.UnauthorizedLogin("No such user"))
but got an error and I think this is the wrong way.
P.S. I know how to do authentication without Perspective Broker...
If you want to implement retry, do it entirely in the client. You should not change the server to report messages like "Bad password" or "No such user", as these leak information to an attacker.
To have the client retry, add an errback to the login Deferred that prompts for a new password (and maybe a new user) and calls login again.
精彩评论