Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46366
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-12 17:58
个人简介

熬着熬着,让时间熬成想要的那个自己,一个美丽的人。

文章分类

全部博文(9)

文章存档

2016年(1)

2014年(7)

2013年(1)

分类: Python/Ruby

2014-02-21 16:43:10


Twisted自带了一个独立协议的,插件式的、异步认证系统

Cred,这个系统可以用于增加任何一种类型的认证支持到你的Twisted server上。通过这个Cred系统Twisted提供一系列常用的认证机制供运用需要的框架。

因为这是个通用的、可扩展系统,即便是一个基本的例子里也会有很多组件需要理解和应用。经过最初步的学习后就可以将Cred应用到实际的系统中,因此跟着我来探索这个系统学习这些例子吧。

首先要明确,这一章节不是关于密码学或者密码管理最佳练习。这章节运用了哈希例子,简单,易于表明Twisted Cred的性能和最小负载;如果你想更多信息更安全的管理用户数据,可以查询另外的与之相关的资源,比如Secure CodingPrinciples and PracticeO Reilly)。

Twisted Cred的组件

在进入应用案例之前,有几条需要熟悉:

Credentials

用于判断认证用户的信息。普通证书是一个用户名和密码,但是实际上可以是任何数据或对象来提供用户的身份,比如说一个证书或者挑战/回应协议。提供证书的对象实现了twisted.cred.credentials.ICredentials

Avatar

server应用里面的一个商业逻辑对象,提供了用户可用的行为和数据。比如,一个邮件serveravatar可能是一个邮箱对象,一个web serveravatar可能是一个资源,一个SSH serveravatar可能是一个远程shell

Avatar ID

由证书核查返回的字符串,用以鉴别一个用户的avatar。通常是一个用户名,但是可以是任何只要是唯一的。例子中的avatar ID有‘Joe Smith,’‘joe@localhost’,和‘user926344’。

Credentials checker证书核查

获取证书并驶入验证 的对象。是各种证书贮存的方式的桥梁,比如,有些在数据库,有的存储在文件中,或者是内存里,或者Cred的其他什么地方。

如果证书正确的鉴定了一个用户,证书核查会返回一个avatar ID.。证书核查也会提供匿名接入,通过twisted.cred.checkders.ANONYMOUS。 

证书核查实现twisted.cred.checkders.ICredentialsChecker接口。

Realm

在一个应用程序中给所有可能的avatar提供接入的对象。一个realm会获取一个avatar ID来识别一个特定的用户,并返回一个avatar对象来代表该用户。一个realm能够支持多种类型的avatar,允许各种不同类型的用户接入一个server中的不同服务。

Portal

入口调解了Cred各部分之间的交互作用。在协议层,你唯一要用到Cred的地方就是给入口portal一个参考。入口的登录方法会给系统验证用户。

入口无法子类化。自由定制只是可以在realmcredential checekeravatars中出现。

Twisted Cred:一个例子

现在我们已经熟悉了定义,接下来我们看看基本的例子。Example9-1显示了一个认证echo server

测试这个echo server,首先运行python echo_cred.py,用telnet命令连接到servertelnet localhost 8000。按照第一行的输入user pass 方能成功登入。你会收到一个登陆成功信息,后面的几行会显示出来。入股欧勇无效的证书登陆会让服务器发起无效登陆的信息并断开连接。下面是客户端登陆的一个例子:

Figure9-1表述了Cred的认证过程的图表。

Figure9-1 Twisted Cred认证过程

步骤如下:

1. 我们的协议工厂EchoFactory,在buildProtocol方法中生成了Echo的实例,就跟第2章一样。与第2章不同的是这些协议有一个参考给Portal

当我们从Echo.lineReceived连接的客户端里面接收第一行,我们调用的我们的Portallogin方法来初始化登录请求。Portal.login的函数签名是logincredentials, mind, *interfaces)。具体来说,这三个参数需求如下:

a. Credentials,证书,在这个例子里就是credentials.UsernamePassword,是从接收到的行里面解析出的用户名和密码。

b. mind’多数情况都是None。在这本书里面我们无需注意这个mind;如果你好奇,Portal.login文档有描述。

c. 我们需要用来验证的avatar接口列表。通常情况下就是一个单独的接口(这个例子里面就是IProtocolAvatar)。

2. Portal网口根据avatar接口请求的,将证书提供给合适的credentials checker证书审查。每一个证书审查提供了一组能够认证的credentialInterface。这个例子只有一个checker审查,就是checkers.InMemoryUsernamePasswordDatabaseDontUse,这是由Twisted提供学习Cred的。这个checker能支持两种类型的证书,checkers.IUsernamePasswordDatabaseDontUsecheckers.IUsernameHashedPassword。因为调用Portal.login是由credentials.UsernamePassword,这是由credentials.IUsernamePassword实现,这个证书核查能认证提供的证书。

3. 一个证书认证返回一个DeferredPortal,包含了证书符合情况下的avatar ID或者登陆失败信息来中断登陆过程来触发Portal.loginerrback回调链。在这个例子中,一个失败会触发Echo._ebLogin

4. 到这里,用户已经成功登陆。Portal激活了RealmrequestAvatar方法,提供了avatarID给合适的avatar接口。

5. requestAvatar返回三组,avatar接口、avatar实例和avatar logout方法。如果在用户登出后没有per-login资源需要去清除,logout方法就什么都不做

6. Portal.login返回一个Deferred包含了avatar接口,avatar实例和avatarlogout方法三元组,或者是登录失败,就如第3步提到的。在这个例子里如果成功_clLogin被调用,发送一个欢迎信息给当下被认证的用户。

一旦认证成功,echo 客户端和服务端就跟第2章一样进行交互。

Credentials Checkers

根据我们所学到的前面最小的例子,我们可以研究为什么Cred的灵活性让它如此强大。首先,假如不用这个袖珍的内存里的checker,我们又如何审查用户名和密码呢,比如说基于文件的用户名和密码数据库?

Twisted还提供了FilePasswordDB checker,因此我们需要做的仅仅是创建一个证书文件包含很多用户名和密码,并在这个FilePasswordDB checker修改:

FilePasswordDB 的行格式是可定制的,默认是用户名:密码。运行echo_cred.py体会一下变化,用passwords.txt来进行。

倘若我们想要在我们的密码文件里面用哈希密码?FilePasswordDB提供了一个可选的哈希参数,可以应用到一个密码上,在比较散列的存储在磁盘上之前。增加Example9-1支持哈希的密码,修改代码如下:

运用相同的哈希逻辑来形成password.txt的密码。

如果我们想把我们的密码存储在数据库里面又如何呢?

Twisted并没有提供一个支持数据库的证书核查,因此我们需要自己写。必须得实现ICredentialsChecker接口,如下:

1.提供一个类不同于credentialsInterfaces,列出这个核查能验证的证书类型

2.实现requestAvatarId方法,如给出一系列证书,必须能认证用户还能返回avatarID或者返回错误信息

Example9-2实习了一个支持数据库的证书核查:

与数据库无关的,一个DBCredentialsChecker进行了初始化实例,包括一个adbapi.ConnectionPool处理,去检索用户证书的查询。

requestAvatarId返回一个包含avatarIDDeferred。这个方法需要一组证书,从这些证书里根据用户名面查询数据库,并验证这些证书提供的密码,与从数据库中查到的比较。一旦密码核查完,Deferred的回调链会被credentials.username激活,这就生成了用户的avatar ID。如果密码不正确,errback回调链会被cred.erro.UnauthorizedLogin

核查checker需要证书实现IUsernameHashedPassword;密码是在被放入数据库之前已经做了散列处理,因此checker不会遇到明文密码,credentials.checkPassword被用户提供的密码激活来验证是否匹配。

我们原来的认证echo server还需要改动的地方就是把DBCredentialsChecker换进去,并把散列的证书放到数据库。修改echo_server.py的下面这些地方:

首先,在文件上方引入哈希模块,以备插入密码到数据库中用:

一个简单的哈希实现跟我们之前修改的例子9-1函数类似。

注:再来提醒一下,这个章节目的在于实现简洁明了的例子。不要用md5加密哈希密码。不要明文储存密码,处理好密码并用加密的安全哈希散列。如果你想获取更多信息关于如何更加安全的管理用户数据,参阅相关内容的资源。你的用户会感谢你的。

Twisted应用认证

目前为止,TwistedCred例子已经用了server,当然是在第6Twisted应用框架之外。TwistedAuthOptionMixin类来使得应用的认证更加简单,实际上Twisted Cred真正赞的地方就是提供一个标准的接口供融合认证机制,而不需考虑你应用的业务逻辑。

把之前的混合的例子9-1echo server 转换为一个Twisted应用。首先,删除realmportalreactor code,用命令twistd和插件来代替,修改server文件:

然后给这个应用创建一个插件,就用Example6-4的例子的模板:在包含server应用的路径下面,创建一个twisted路径来存放包含echo_cred_plugin.py的插件路径。Example9-3就是插件代码。

echo_cred_plugin.py看上去跟6-4例子里的非常相似,只有一点不同:认证EchoFactory需要Portal接口,Portal接口又需要Realm接口和注册认证核查。我们需要用命令行配置可用的证书核查,为此我们需要我们的命令行参数是继承自strcred.AuthOptionMixin

运用strcred.AuthOptionMixin,我们需要做的就是在supportedInterfaces类变量里列举出支持的证书类型;这能让我们访问命令行参数设置。比如这个例子,我们重用了我们之前用过的证书类型credentials.IUsernamePassword

这个可AuthOptionMixin的插件,twistd echo生成了命令行认证配置和文档:

让我们试一下我们的认证echo server,用twistd运行Example9-1checkers.InMemoryUsernamePasswordDatabaseDontUse的命令行版:

如常一样,我们可以运行telnet来连接server

没有应用配置,我们可以转向认证密码文件就像是passwords.txt根据文件认证类型:

Unix系统,我们甚至可以用一个内置的unix 核查器,试图用每一个可利用资源来认证本地UNIX系统所有的用户列表,目前包括验证/etc/passwd/etc/shadow

你可以用你的本机登录名和密码来验证echo server

倘若我们想增加一个自己编写的checker到可用的命令行checke池里面,不是内存、文件或unix又该怎么办?

正如你所猜想的,我们就用插件。如果你查看twisted/plugins/Twisted的源代码,你会看一个cred_*文件配置给每一个我们目前用到的checker,其他可能也有。每一个Cred 插件实现并提供了一个证书核查工厂。Twistd --help-auth里提供的证书核查列表是一组证书,这些证书实现了.AuthOptionMixinsupportedInterfaces列出的证书接口,存储在你server的插件文件里。在这个echo 例子里,我们列举了credentials.IUsernamePassword,因此可用的核查就放在twisted/plugins,在credentialInterface中列表IUsernamePassword

因此,增加自己的checker核查给一个指定的证书接口到twistd,我们需要存储证书核查和工厂插件到我们顶层项目的twisted/plugins子路径。之后核查会作为参数显示,用twisted --help-auth可查看

更多练习和下一步计划

这个章节讨论了TwistedCred认证系统。在Cred模型里,协议认证用户通过验证证书有效性的Portal连到证书核查并返回一个avataravatar能以被认证用户的名义进行操作。Cred用第6章介绍的插件系统组成一个通用的可扩展的框架。


阅读(1305) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~