3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Authentication\Adapter\Http
;
12 use Zend\Stdlib\ErrorHandler
;
15 * HTTP Authentication File Resolver
17 class FileResolver
implements ResolverInterface
20 * Path to credentials file
29 * @param string $path Complete filename where the credentials are stored
31 public function __construct($path = '')
34 $this->setFile($path);
39 * Set the path to the credentials file
42 * @return FileResolver Provides a fluent interface
43 * @throws Exception\InvalidArgumentException if path is not readable
45 public function setFile($path)
47 if (empty($path) ||
!is_readable($path)) {
48 throw new Exception\
InvalidArgumentException('Path not readable: ' . $path);
56 * Returns the path to the credentials file
60 public function getFile()
68 * Only the first matching username/realm combination in the file is
69 * returned. If the file contains credentials for Digest authentication,
70 * the returned string is the password hash, or h(a1) from RFC 2617. The
71 * returned string is the plain-text password for Basic authentication.
73 * The expected format of the file is:
74 * username:realm:sharedSecret
76 * That is, each line consists of the user's username, the applicable
77 * authentication realm, and the password or hash, each delimited by
80 * @param string $username Username
81 * @param string $realm Authentication Realm
82 * @return string|false User's shared secret, if the user is found in the
83 * realm, false otherwise.
84 * @throws Exception\ExceptionInterface
86 public function resolve($username, $realm, $password = null)
88 if (empty($username)) {
89 throw new Exception\
InvalidArgumentException('Username is required');
90 } elseif (!ctype_print($username) ||
strpos($username, ':') !== false) {
91 throw new Exception\
InvalidArgumentException('Username must consist only of printable characters, '
92 . 'excluding the colon');
95 throw new Exception\
InvalidArgumentException('Realm is required');
96 } elseif (!ctype_print($realm) ||
strpos($realm, ':') !== false) {
97 throw new Exception\
InvalidArgumentException('Realm must consist only of printable characters, '
98 . 'excluding the colon.');
101 // Open file, read through looking for matching credentials
102 ErrorHandler
::start(E_WARNING
);
103 $fp = fopen($this->file
, 'r');
104 $error = ErrorHandler
::stop();
106 throw new Exception\
RuntimeException('Unable to open password file: ' . $this->file
, 0, $error);
109 // No real validation is done on the contents of the password file. The
110 // assumption is that we trust the administrators to keep it secure.
111 while (($line = fgetcsv($fp, 512, ':')) !== false) {
112 if ($line[0] == $username && $line[1] == $realm) {
113 $password = $line[2];