Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍)
原文:Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍)
Zend\Authentication
组件提供了认证接口和具体的通用的认证适配器。Zend\Authentication
所关注的是认证通过和不通过,认证被宽松地定义为确定一个实体是否确实是它所声称(例如,身份),基于一些组凭据。授权是一个过程,决定是否允许访问的实体,或执行操作时,其它实体在Zend\Authentication
范围之外。欲了解Zend Framework授权和访问控制更多信息,请关注Zend\Permissions\Acl 和Zend\Permissions\Rbac组件。
注意:并没有
Zend\Authentication\Authentication
class,而是由Zend\Authentication\AuthenticationService
提供,这个类的内部使用底层的认证适配器和持久性存储。
Adapters
Zend\Authentication
适配器是用来一个特定类型进行身份验证的服务,例如LDAP, RDBMS或文件。不同的适配器可能有不同的选项和行为,但都是认证适配器。例如,接受认证证书(包括身份声明),依靠认证服务执行查询,并返回结果是Zend\Authentication
适配器共同特征。
每个Zend\Authentication
适配器都实现自Zend\Authentication\Adapter\AdapterInterface
接口,这个接口定义了方法authenticate()
,一个适配器类必须实现认证查询。每个适配器类调用之前必须先准备好authenticate()
。这样适配器准备包括设置证书(例如,用户名和密码)和特定于适配器的配置选项,如数据库连接设置一个数据库表适配器的定义值。
下面是一个认证适配器的例子,需要一个用户名和密码为认证设置。其他的细节,比如如何查询认证服务,已为简洁起见省略:
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
|
use Zend\Authentication\Adapter\AdapterInterface; class My\Auth\Adapter implements AdapterInterface { /** * Sets username and password for authentication * * @return void */ public function __construct( $username , $password ) { // ... } /** * Performs an authentication attempt * * @return \Zend\Authentication\Result * @throws \Zend\Authentication\Adapter\Exception\ExceptionInterface * If authentication cannot be performed */ public function authenticate() { // ... } } |
正如上面所示,authenticate()
必须返回的Zend\Authentication\Result
中(或从Zend\Authentication\Result
派生的类)的一个实例。如果出于某种原因进行认证查询是不可能的,authenticate()
应该抛出一个派生自Zend\Authentication\Adapter\Exception\ExceptionInterface
的异常。
Results
Zend\Authentication
适配器的返回一个Zend\Authentication\Result
实例,以表示一个认证尝试的结果。适配器构造Zend\Authentication\Result
对象后,提供了4个基本的方法:
isValid()
如果认证成功返回true
getCode()
返回Zend\Authentication\Result
常量用来确定类型的身份验证失败或成功是否已经发生。这可以用若干认证结果类型的开发者希望区别的情况下。这将允许开发者维护详细的认证结果统计,例如。此功能的另一个用途是提供特定的,定制的信息给用户可用性的原因,虽然开发商被鼓励去考虑提供这样详细的原因给用户,而不是一个一般的认证失败消息的风险。欲了解更多信息,请参见下面的注释。getIdentity()
返回认证后的身份getMessages()
返回认证尝试失败的消息数组
开发者可能希望根据认证结果的类型分支,以执行更具体的操作。开发人员可能会发现有用的一些操作太多的不成功的密码尝试后锁定账户,太多不存在的身份尝试后标记IP地址,并提供专用的,定制的认证结果信息给用户。下面的结果代码可供选择:
1
2
3
4
5
6
7
8
|
use Zend\Authentication\Result; Result::SUCCESS Result::FAILURE Result::FAILURE_IDENTITY_NOT_FOUND Result::FAILURE_IDENTITY_AMBIGUOUS Result::FAILURE_CREDENTIAL_INVALID Result::FAILURE_UNCATEGORIZED |
下面的例子说明了开发人员如何可能的结果代码分支:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// inside of AuthController / loginAction $result = $this ->auth->authenticate( $adapter ); switch ( $result ->getCode()) { case Result::FAILURE_IDENTITY_NOT_FOUND: /** do stuff for nonexistent identity **/ break ; case Result::FAILURE_CREDENTIAL_INVALID: /** do stuff for invalid credential **/ break ; case Result::SUCCESS: /** do stuff for successful authentication **/ break ; default : /** do stuff for other failure **/ break ; } |
身份持久存储(Identity Persistence)
验证请求包含认证证书本身是有用的,但它也是重要的是要维护已认证的身份,而无需出示认证证书,每个请求。
HTTP是一个无状态的协议,然而,为了方便在服务器端Web应用程序跨多个请求维护状态,已经开发技术,如cookie和session。
默认的php session持久存储
Zend\Authentication
提供了成功认证后默认的持久性存储的身份PHP的session。成功认证后,Zend\Authentication\AuthenticationService::authenticate()
将认证后的身份存储到持久存储器。除非另有配置,Zend\Authentication\AuthenticationService
默认使用Zend\Authentication\Storage\Session
持久存储器,它反来使用了Zend\Session
。你也可以用Zend\Authentication\AuthenticationService::setStorage()
自定义一个对象只需要实现Zend\Authentication\Storage\StorageInterface
接口。
注意:如果持久存储的身份不适合特定的用例,然后,开发人员可能会忘记使直接使用适配器类替代
Zend\Authentication\AuthenticationService
修改session的命名空间
Zend\Authentication\Storage\Session
使用的命名空间名是Zend_Auth
,可以通过Zend\Authentication\Storage\Session
构造方法传递不同的值来覆盖这个命名空间名,这个值从内部传递给Zend\Session\Container
构造方法。这个操作得在尝试认证Zend\Authentication\AuthenticationService::authenticate()
执行自动身份存储之前。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
use Zend\Authentication\AuthenticationService; use Zend\Authentication\Storage\Session as SessionStorage; $auth = new AuthenticationService(); // Use 'someNamespace' instead of 'Zend_Auth' $auth ->setStorage( new SessionStorage( 'someNamespace' )); /** * @todo Set up the auth adapter, $authAdapter */ // Authenticate, saving the result, and persisting the identity on // success $result = $auth ->authenticate( $authAdapter ); |
链式存储(Chain Storage)
一个网站可能有多个存储,Chain
存储很好的把他们链接在一起。
例如:Chain
可以配置为先使用Session
存储,然后使用OAuth
存储,可能的配置代码如下:
1
2
3
|
$storage = new Chain; $storage ->add( new Session); $storage ->add( new OAuth); // Note: imaginary storage, not part of ZF2 |
现在,如果Chain
存储访问其底层存储访问的顺序,它们被添加到链。因此,首先使用的是Session
存储使用。现在无论怎样都是:
Session
存储非空的话,Chain
将使用它的内容- 如果
Session
为空,OAuth
存储将被访问- 如果也是空的话,那么链式存储也为空
- 只要其中一个非空的
Chain
,就将使用其内容。然而,它们也有各自的优先级。因此Session
存储的也可能是Oauth
存储的内容。
其实使用Chain::add
方法可以设置存储的优先级的:
1
2
|
$chain ->add( new A, 2); $chain ->add( new B, 10); // First use B |
实现自定义存储
Zend\Authentication\Storage\Session
为开发人提供了不同机制身份存储,对于这样的情况下,开发人员可以简单地实现Zend\Authentication\Storage\StorageInterface
接口和提供实例给Zend\Authentication\AuthenticationService::setStorage()
。
使用自定义存储类
为了使用Zend\Authentication\Storage\Session
以外的身份持久存储,开发者需要实现Zend\Authentication\Storage\StorageInterface
接口:
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
62
63
64
65
66
67
|
use Zend\Authentication\Storage\StorageInterface; class My\Storage implements StorageInterface { /** * Returns true if and only if storage is empty * * @throws \Zend\Authentication\Exception\ExceptionInterface * If it is impossible to * determine whether storage is empty * @return boolean */ public function isEmpty() { /** * @todo implementation */ } /** * Returns the contents of storage * * Behavior is undefined when storage is empty. * * @throws \Zend\Authentication\Exception\ExceptionInterface * If reading contents from storage is impossible * @return mixed */ public function read() { /** * @todo implementation */ } /** * Writes $contents to storage * * @param mixed $contents * @throws \Zend\Authentication\Exception\ExceptionInterface * If writing $contents to storage is impossible * @return void */ public function write( $contents ) { /** * @todo implementation */ } /** * Clears contents from storage * * @throws \Zend\Authentication\Exception\ExceptionInterface * If clearing contents from storage is impossible * @return void */ public function clear() { /** * @todo implementation */ } } |
为了使用这个存储类,需要在认证查询尝试之前调用Zend\Authentication\AuthenticationService::setStorage()
进行存储类的设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
use Zend\Authentication\AuthenticationService; // Instruct AuthenticationService to use the custom storage class $auth = new AuthenticationService(); $auth ->setStorage( new My\Storage()); /** * @todo Set up the auth adapter, $authAdapter */ // Authenticate, saving the result, and persisting the identity on // success $result = $auth ->authenticate( $authAdapter ); |
使用方法
两种方法可以使用Zend\Authentication
:
- 通过
Zend\Authentication\AuthenticationService::authenticate()
间接使用 - 直接通过适配器使用
authenticate()
下面例子介绍如何通过类Zend\Authentication\AuthenticationService
间接使用Zend\Authentication
适配器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
use Zend\Authentication\AuthenticationService; // instantiate the authentication service $auth = new AuthenticationService(); // Set up the authentication adapter $authAdapter = new My\Auth\Adapter( $username , $password ); // Attempt authentication, saving the result $result = $auth ->authenticate( $authAdapter ); if (! $result ->isValid()) { // Authentication failed; print the reasons why foreach ( $result ->getMessages() as $message ) { echo "$message\n" ; } } else { // Authentication succeeded; the identity ($username) is stored // in the session // $result->getIdentity() === $auth->getIdentity() // $result->getIdentity() === $username } |
一旦认证已经尝试在一个请求,在上面的例子中,它是一个简单的事情,以检查是否存在成功验证的身份:
1
2
3
4
5
6
7
8
9
10
11
12
|
use Zend\Authentication\AuthenticationService; $auth = new AuthenticationService(); /** * @todo Set up the auth adapter, $authAdapter */ if ( $auth ->hasIdentity()) { // Identity exists; get it $identity = $auth ->getIdentity(); } |
要从持久性存储删除身份,简单的使用clearIdentity()
方法就好,这通常会被用于应用中的“登出”操作。
1
|
$auth ->clearIdentity(); |
简单的使用Zend\Authentication\AuthenticationService
对于个别项目是不适合的,这个时候需要直接使用适配器类,直接使用适配器类需要配置和准备适配器对象,然后调用其authenticate()
方法。适配器的具体细节在各自的文档中进行了说明。下面的例子直接利用My\Auth\Adapter
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Set up the authentication adapter $authAdapter = new My\Auth\Adapter( $username , $password ); // Attempt authentication, saving the result $result = $authAdapter ->authenticate(); if (! $result ->isValid()) { // Authentication failed; print the reasons why foreach ( $result ->getMessages() as $message ) { echo "$message\n" ; } } else { // Authentication succeeded // $result->getIdentity() === $username }
|
Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍)的更多相关文章
- Zend Framework 2参考Zend\Authentication(摘要式身份验证)
Zend Framework 2参考Zend\Authentication(摘要式身份验证) 介绍 摘要式身份验证是HTTP身份验证的方法,提高了基本身份验证时提供的方式进行身份验证,而无需在网络上以 ...
- Zend Framework 2参考Zend\Authentication(HTTP认证适配器)
Zend Framework 2参考Zend\Authentication(HTTP认证适配器) 介绍 Zend\Authentication\Adapter\Http提供了RFC-2617, Bas ...
- Zend Framework 2参考Zend\Authentication(数据库表认证)
+ 转载自:Zend Framework 2参考Zend\Authentication(数据库表认证) 介绍 Zend\Authentication\Adapter\DbTable提供对存储在数据库表 ...
- zend framework 1.10项目配置与经典hello world
准备工作 前置条件:PHP>=5.14,Apache开启mod_rewrite支持,开启php的pdo扩展. Zend Framework 要求 PHP版本不低于5.1.4,但强烈建议使用 5. ...
- Zend Framework 留言本实战(转)
一.环境搭建和ZF安装 *[注]本节内容大部分来至Zend Framework官方手册 1.1 Zend Framework下载 Zend Framework 使 ...
- Zend Framework 1 - Quick Start
创建 Zend 项目 要创建 Zend 项目,首先要下载并解压 Zend Framework. 安装 Zend Framework 下载最新的 Zend Framework 1.12.20 源码包,( ...
- Ubuntu14.0下安装Zend Framework 2
Ubuntu14.0下安装Zend Framework 2为了安装这个东西,忙活了快一天了,参考中文博客一直没有安装成功,有些博客的时间也是已经很早了,后来google看英文版的才安装成功,这里记录一 ...
- Zend Framework 入门(1)—快速上手
1. 安装 从 Zend Framework 的网页上下载最新版本.解压后,把整个目录拷贝到一个理想的地方,比如:/php/library/Zend. 打开 php.ini 文件,确认包含 Zend ...
- Zend Framework XML外部实体和安全绕过漏洞
漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...
随机推荐
- mac下Apache + MySql + PHP网站开发
最近接了个小活,做一个使用PHP语言和MySql数据库的动态网站.之前做过类型的网站,是在windows系统下做的,开发环境使用的是 AppServ 的PHP开发套件.现在有了我的大MAC,所以找了M ...
- 2、.net NVelocity中原生javascript ajax封装使用
在页面上,我们经常会遇到局部刷新的例子,这个时候,就需要用到ajax, 因为很多代码都是公用的,所以我们想到了,将代码封装,简化了使用,减少了冗余 javascript ajax代码如下: var x ...
- easyui的datagrid组件,如何设置点击某行不会高亮该行的方式
easyui的datagrid组件,有些时候我们点击某行不想高亮显示,如何设置点击某行不会高亮该行的方式,有好几种方法可以实现,我举几个,可以根据你具体需求灵活应用: 1.修改easyui的css将高 ...
- 剖析Qt的事件机制原理
版权声明 请尊重原创作品.转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口程序.消息循环和WinMai ...
- CTO的眼界到底有多宽?
CTO的眼界到底有多宽? [CSDN独家报道]在各大企业中,CTO (Chief Technology Officer,首席技术官)有着雄厚的技术实力,掌握着企业核心技术,是软件开发项目中最重要的人 ...
- MySQL优化器cost计算
记录MySQL 5.5上,优化器进行cost计算的方法. 第一篇: 单表的cost计算 数据结构: 1. table_share: 包含了表的元数据,其中索引部分: key_info:一个key的结构 ...
- bzoj2209 2329
括号序列的经典做法把(看成1,)看成-1匹配的括号序列即任意前缀和都非负我们先解决静态的问题,给定一段括号序列求最少修改次数我们先找出最大后缀和a和最小前缀和b之间一定可以不相交显然a+|b|个括号是 ...
- android基本的数据库创建和使用
android的四大组件中就有Content Provider,对其他应用,提供自己的数据,所以,一般情况下,android应用不需要提供content provider. 1. 简单的数据库表单字 ...
- Android权限Uri.parse
1,调web浏览器 Uri myBlogUri = Uri.parse("http://xxxxx.com"); returnIt = new Intent(Intent.ACTI ...
- 海量jQuery插件
转自:http://blog.csdn.net/zzq58157383/article/details/6900142 提醒大家在使用的时候注意jQuery包的版本问题,最好是使用相同的版本,因为使用 ...