简介Zend_Auth 为认证(authentication)和一些通用用例情景的具体认证适配器提供了一个API。 Zend_Auth 只涉及 认证而不是授权。认证被宽松地定义为基于一些证书(credential)来确定一个实体(例如,身份)是否确实是它所声称的。授权是一个过程,它决定是否允许一个实体对其他实体进行访问、执行操作,它超出了Zend_Auth的范围。更多关于Zend Framework 授权和访问控制的信息,参见Zend_Acl.
适配器Zend_Auth适配器被用来依靠特定的认证服务(例如LDAP、RDBMS或基于文件的存储)来认证。不同的适配器可能有不同的选项和行为,但有些基本的事情在认证适配器中是通用的。例如,接受认证证书(包括声称身份)、依靠认证服务执行查询、返回结果在Zend_Auth适配器中是通用的。
每个Zend_Auth适配器类都实现 下面是一个认证适配器的例子,它要求为认证设置用户名和密码。为简明扼要,其它的细节(如查询认证服务)被省略了。
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
/**
* Sets username and password for authentication
*
* @return void
*/
public function __construct($username, $password)
{
// ...
}
/**
* Performs an authentication attempt
*
* @throws Zend_Auth_Adapter_Exception If authentication cannot
* be performed
* @return Zend_Auth_Result
*/
public function authenticate()
{
// ...
}
}
authenticate()必需返回一个Zend_Auth_Result的实例(或从Zend_Auth_Result派生的一个类的实例)。如果因为某些原因认证查询不能执行,authenticate()应该抛出一个由Zend_Auth_Adapter_Exception产生的异常。
结果
为了表示一个认证尝试的结果,Zend_Auth适配器返回一个带有
为了执行更多的操作,开发者可能希望基于认证结果的类型来分支化。一些开发者可能发信有用的操作是:在太多的不成功的密码尝试之后锁住帐号,在太多不存在的身份尝试后标记IP地址,并提供专用的,定制的认证结果信息给用户。下面的结果代码是可用的:
Zend_Auth_Result::SUCCESS
Zend_Auth_Result::FAILURE
Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
Zend_Auth_Result::FAILURE_UNCATEGORIZED
下面的例子举例说明开发者如何分支化结果代码:
// inside of AuthController / loginAction
$result = $this->_auth->authenticate($adapter);
switch ($result->getCode()) {
case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
/** do stuff for nonexistent identity **/
break;
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
/** do stuff for invalid credential **/
break;
case Zend_Auth_Result::SUCCESS:
/** do stuff for successful authentication **/
break;
default:
/** do stuff for other failure **/
break;
}
身份的持久(Persistence)实质上,认证一个包含认证证书的请求很有用,但是维护已认证的身份并在每次请求时不需要出示认证证书也同样很重要。 HTTP是一个无连接的协议,然而,象cookie和session这样的技术已经被开发出来使在服务器端的web应用维护多请求状态变得容易。 在PHP Session 中的缺省持久(Persistence)
缺省地,
Example #1 修改 Session 名字空间
// Save a reference to the Singleton instance of Zend_Auth
$auth = Zend_Auth::getInstance();
// Use 'someNamespace' instead of 'Zend_Auth'
$auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
/**
* @todo Set up the auth adapter, $authAdapter
*/
// Authenticate, saving the result, and persisting the identity on
// success
$result = $auth->authenticate($authAdapter);
实现订制存储
有时候开发者需要使用不同的身份持久行为,而不是 Example #2 使用定制存储类
为了使用不同于
class MyStorage implements Zend_Auth_Storage_Interface
{
/**
* Returns true if and only if storage is empty
*
* @throws Zend_Auth_Storage_Exception 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_Auth_Storage_Exception If reading contents from
* storage is impossible
* @return mixed
*/
public function read()
{
/**
* @todo implementation
*/
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws Zend_Auth_Storage_Exception If writing $contents to
* storage is impossible
* @return void
*/
public function write($contents)
{
/**
* @todo implementation
*/
}
/**
* Clears contents from storage
*
* @throws Zend_Auth_Storage_Exception If clearing contents from
* storage is impossible
* @return void
*/
public function clear()
{
/**
* @todo implementation
*/
}
}
为了使用这个定制的存储类,在认证查询被尝试前,
// Instruct Zend_Auth to use the custom storage class
Zend_Auth::getInstance()->setStorage(new MyStorage());
/**
* @todo Set up the auth adapter, $authAdapter
*/
// Authenticate, saving the result, and persisting the identity on
// success
$result = Zend_Auth::getInstance()->authenticate($authAdapter);
使用Zend_Auth这里提供了两种方法使用Zend_Auth适配器:
下面的例子通过
// Get a reference to the singleton instance of Zend_Auth
require_once 'Zend/Auth.php';
$auth = Zend_Auth::getInstance();
// Set up the authentication adapter
$authAdapter = new MyAuthAdapter($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
}
一旦在一个请求里的认证被尝试,如上面的例子,检查一个成功的被认证的身份是否存在就是一个简单的匹配:
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
// Identity exists; get it
$identity = $auth->getIdentity();
}
从持久存储空间出去一个身份,可简单地使用
Zend_Auth::getInstance()->clearIdentity();
当自动使用持久存储空间对特定的用例不合适,开发者可简单地忽略
// Set up the authentication adapter
$authAdapter = new MyAuthAdapter($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
}
|