1010 * derivative class is provided under the MIT public license.
1111 *
1212 * @author Josh Lockhart <[email protected] > 13+ * @author Samer Bechara <[email protected] > 1314 * @version 1.0
1415 *
1516 * USAGE
1617 *
1718 * $app = new Slim();
18- * $app->add(new HttpDigestAuth('theUsername' , 'thePassword' ));
19+ * $app->add(new HttpDigestAuth(array('user1' => 'password1' , 'user2' => 'password2') ));
1920 *
2021 * MIT LICENSE
2122 *
3839 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
3940 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4041 */
41- namespace Slim \Extras \Middleware ;
42-
43- class HttpDigestAuth extends \Slim \Middleware
44- {
45- /**
46- * @var string
47- */
48- protected $ username ;
49-
42+ class HttpDigestAuth extends Slim_Middleware {
5043 /**
51- * @var string
44+ * @var array
5245 */
53- protected $ password ;
46+ protected $ credentials ;
5447
5548 /**
5649 * @var string
@@ -60,15 +53,14 @@ class HttpDigestAuth extends \Slim\Middleware
6053 /**
6154 * Constructor
6255 *
63- * @param string $username The HTTP Authentication username
64- * @param string $password The HTTP Authentication password
56+ * @param array $credentials An array of usernames and passwords
6557 * @param string $realm The HTTP Authentication realm
6658 * @return void
6759 */
68- public function __construct ($ username , $ password , $ realm = 'Protected Area ' )
69- {
70- $ this -> username = $ username ;
71- $ this ->password = $ password ;
60+ public function __construct ( $ credentials , $ realm = 'Protected Area ' ) {
61+
62+
63+ $ this ->credentials = $ credentials ;
7264 $ this ->realm = $ realm ;
7365 }
7466
@@ -81,25 +73,24 @@ public function __construct($username, $password, $realm = 'Protected Area')
8173 *
8274 * @return void
8375 */
84- public function call ()
85- {
76+ public function call () {
8677 //Check header and header username
87- if (empty ($ _SERVER ['PHP_AUTH_DIGEST ' ])) {
78+ if ( empty ($ _SERVER ['PHP_AUTH_DIGEST ' ]) ) {
8879 $ this ->fail ();
8980 return ;
9081 } else {
9182 $ data = $ this ->parseHttpDigest ($ _SERVER ['PHP_AUTH_DIGEST ' ]);
92- if (!$ data || $ data ['username ' ] !== $ this ->username ) {
83+ if ( !$ data || ! array_key_exists ( $ data ['username ' ], $ this ->credentials ) ) {
9384 $ this ->fail ();
9485 return ;
9586 }
9687 }
9788
9889 //Check header response
99- $ A1 = md5 ($ data ['username ' ] . ': ' . $ this ->realm . ': ' . $ this ->password );
90+ $ A1 = md5 ($ data ['username ' ] . ': ' . $ this ->realm . ': ' . $ this ->credentials [ $ data [ ' username ' ]] );
10091 $ A2 = md5 ($ _SERVER ['REQUEST_METHOD ' ] . ': ' . $ data ['uri ' ]);
10192 $ validResponse = md5 ($ A1 . ': ' . $ data ['nonce ' ] . ': ' . $ data ['nc ' ] . ': ' . $ data ['cnonce ' ] . ': ' . $ data ['qop ' ] . ': ' . $ A2 );
102- if ($ data ['response ' ] !== $ validResponse ) {
93+ if ( $ data ['response ' ] !== $ validResponse ) {
10394 $ this ->fail ();
10495 return ;
10596 }
@@ -113,44 +104,25 @@ public function call()
113104 *
114105 * @return void
115106 */
116- protected function fail ()
117- {
107+ protected function fail () {
118108 $ this ->app ->response ()->status (401 );
119- $ this ->app ->response ()->header (
120- 'WWW-Authenticate ' ,
121- sprintf (
122- 'Digest realm="%s",qop="auth",nonce="%s",opaque="%s" ' ,
123- $ this ->realm ,
124- uniqid (),
125- md5 ($ this ->realm )
126- )
127- );
109+ $ this ->app ->response ()->header ('WWW-Authenticate ' , sprintf ('Digest realm="%s",qop="auth",nonce="%s",opaque="%s" ' , $ this ->realm , uniqid (), md5 ($ this ->realm )));
128110 }
129111
130112 /**
131113 * Parse HTTP Digest Authentication header
132114 *
133115 * @return array|false
134116 */
135- protected function parseHttpDigest ($ headerValue )
136- {
137- $ needed_parts = array (
138- 'nonce ' => 1 ,
139- 'nc ' => 1 ,
140- 'cnonce ' => 1 ,
141- 'qop ' => 1 ,
142- 'username ' => 1 ,
143- 'uri ' => 1 ,
144- 'response ' => 1
145- );
117+ protected function parseHttpDigest ( $ headerValue ) {
118+ $ needed_parts = array ('nonce ' => 1 , 'nc ' => 1 , 'cnonce ' => 1 , 'qop ' => 1 , 'username ' => 1 , 'uri ' => 1 , 'response ' => 1 );
146119 $ data = array ();
147120 $ keys = implode ('| ' , array_keys ($ needed_parts ));
148121 preg_match_all ('@( ' . $ keys . ')=(?:([ \'"])([^\2]+?)\2|([^\s,]+))@ ' , $ headerValue , $ matches , PREG_SET_ORDER );
149- foreach ($ matches as $ m ) {
122+ foreach ( $ matches as $ m ) {
150123 $ data [$ m [1 ]] = $ m [3 ] ? $ m [3 ] : $ m [4 ];
151124 unset($ needed_parts [$ m [1 ]]);
152125 }
153-
154126 return $ needed_parts ? false : $ data ;
155127 }
156- }
128+ }
0 commit comments