原文: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介绍)的更多相关文章

  1. Zend Framework 2参考Zend\Authentication(摘要式身份验证)

    Zend Framework 2参考Zend\Authentication(摘要式身份验证) 介绍 摘要式身份验证是HTTP身份验证的方法,提高了基本身份验证时提供的方式进行身份验证,而无需在网络上以 ...

  2. Zend Framework 2参考Zend\Authentication(HTTP认证适配器)

    Zend Framework 2参考Zend\Authentication(HTTP认证适配器) 介绍 Zend\Authentication\Adapter\Http提供了RFC-2617, Bas ...

  3. Zend Framework 2参考Zend\Authentication(数据库表认证)

    + 转载自:Zend Framework 2参考Zend\Authentication(数据库表认证) 介绍 Zend\Authentication\Adapter\DbTable提供对存储在数据库表 ...

  4. zend framework 1.10项目配置与经典hello world

    准备工作 前置条件:PHP>=5.14,Apache开启mod_rewrite支持,开启php的pdo扩展. Zend Framework 要求 PHP版本不低于5.1.4,但强烈建议使用 5. ...

  5. Zend Framework 留言本实战(转)

    一.环境搭建和ZF安装              *[注]本节内容大部分来至Zend Framework官方手册       1.1 Zend Framework下载 Zend Framework 使 ...

  6. Zend Framework 1 - Quick Start

    创建 Zend 项目 要创建 Zend 项目,首先要下载并解压 Zend Framework. 安装 Zend Framework 下载最新的 Zend Framework 1.12.20 源码包,( ...

  7. Ubuntu14.0下安装Zend Framework 2

    Ubuntu14.0下安装Zend Framework 2为了安装这个东西,忙活了快一天了,参考中文博客一直没有安装成功,有些博客的时间也是已经很早了,后来google看英文版的才安装成功,这里记录一 ...

  8. Zend Framework 入门(1)—快速上手

    1. 安装 从 Zend Framework 的网页上下载最新版本.解压后,把整个目录拷贝到一个理想的地方,比如:/php/library/Zend. 打开 php.ini 文件,确认包含 Zend ...

  9. Zend Framework XML外部实体和安全绕过漏洞

    漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...

随机推荐

  1. 4种方法生成二维码 (js 控制canvas 画出 二维码)

    随着网络的迅速发展 发展 发展,二维码的应用将会越来越多.同时很多只是很平凡的二维码,请拿起你的手 把这个二维码 设计起来吧.下面分享了几个非常好的二维码设计.  二维码原理: 二维条码/二维码可以分 ...

  2. xcopy总是询问是文件名还是目录名

    我需要运行类似xcopy /y a.xml .\pics\b.xml很多次,但xcopy总是问我“文件名还是目录名” 可以这样通过管道来做echo f | xcopy /y a.xml .\pics\ ...

  3. 股票API

    实时股票数据接口大全 股票数据的获取目前有如下两种方法可以获取:1. http/javascript接口取数据2. web-service接口 1.http/javascript接口取数据 1.1Si ...

  4. (九)groupByKey,reduceByKey,sortByKey算子-Java&Python版Spark

    groupByKey,reduceByKey,sortByKey算子 视频教程: 1.优酷 2. YouTube 1.groupByKey groupByKey是对每个key进行合并操作,但只生成一个 ...

  5. 国内外最全的asp.net开源项目 (转)

    最近一些项目开始用到CMS系统,最开始是研究JAVA的,无奈国内JAVA的CMS开源系统还是比较少,最多最成熟的还是PHP的,当然现在.NET的也不少了,这里做一下汇总备忘,留待学习研究. 国内系统: ...

  6. 《Linux命令行大全》系列(三、Linux 系统)

    在<Linux命令行大全>一书中,第3章名称是 Linux 系统. 概念太大,不过该节内容却是 Linux 系统最为核心的基础——查看 Linux 系统. ls 命令 显示目录自身信息或目 ...

  7. 50个实用的jQuery代码段让你成为更好的Web前端工程师

    本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助 ...

  8. c# gzip解压缩

                , bytes.Length)) > )             {                line =  System.Text.Encoding.Defaul ...

  9. 算法练习之:Doubles

    Doubles Time Limit: 1000MS Memory Limit: 65536KB Problem Description As part of an arithmetic compet ...

  10. 又爱又恨的BOOTSTRAP

    搞本书,看了一天,确实,,UIKIT比它好用... 但,艺多不压身吧. 今天自己抄了个大概的,不用其它插件,,但那手风琴,真的找了很多,没有中意的... <!DOCTYPE html> & ...