Auth.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\net\http;
  9. /**
  10. * The `Auth` class handles HTTP Authentication encoding and decode. Typically, this class is not
  11. * used directly, but is a utility of `action\Request` and `security\auth\adapter\Http`
  12. */
  13. class Auth extends \lithium\core\StaticObject {
  14. /**
  15. * The NC value needed for digest authentication
  16. *
  17. */
  18. public static $nc = '00000001';
  19. /**
  20. * Returns the proper header string. Accepts the data from the `encode` method.
  21. *
  22. * @param array $data
  23. * @return string
  24. */
  25. public static function header($data) {
  26. if (empty($data['response'])) {
  27. return null;
  28. }
  29. if (!empty($data['opaque'])) {
  30. $defaults = array(
  31. 'realm' => 'app', 'method' => 'GET', 'uri' => '/',
  32. 'username' => null, 'qop' => 'auth',
  33. 'nonce' => null, 'opaque' => null,
  34. 'cnonce' => md5(time()), 'nc' => static::$nc
  35. );
  36. $data += $defaults;
  37. $auth = "username=\"{$data['username']}\", response=\"{$data['response']}\", ";
  38. $auth .= "uri=\"{$data['uri']}\", realm=\"{$data['realm']}\", ";
  39. $auth .= "qop=\"{$data['qop']}\", nc={$data['nc']}, cnonce=\"{$data['cnonce']}\", ";
  40. $auth .= "nonce=\"{$data['nonce']}\", opaque=\"{$data['opaque']}\"";
  41. return "Digest " . $auth;
  42. }
  43. return "Basic " . $data['response'];
  44. }
  45. /**
  46. * Encoded the data with username and password to create the proper response. Returns an array
  47. * containing the username and encoded response.
  48. *
  49. * @param string $username Username to authenticate with
  50. * @param string $password Password to authenticate with
  51. * @param array $data Params needed to hash the response
  52. * @return array
  53. */
  54. public static function encode($username, $password, $data = array()) {
  55. if (isset($data['nonce'])) {
  56. $defaults = array(
  57. 'realm' => 'app', 'method' => 'GET', 'uri' => '/', 'qop' => null,
  58. 'cnonce' => md5(time()), 'nc' => static::$nc
  59. );
  60. $data = array_filter($data) + $defaults;
  61. $part1 = md5("{$username}:{$data['realm']}:{$password}");
  62. $part2 = "{$data['nonce']}:{$data['nc']}:{$data['cnonce']}:{$data['qop']}";
  63. $part3 = md5($data['method'] . ':' . $data['uri']);
  64. $response = md5("{$part1}:{$part2}:{$part3}");
  65. return compact('username', 'response') + $data;
  66. }
  67. $response = base64_encode("{$username}:{$password}");
  68. return compact('username', 'response');
  69. }
  70. /**
  71. * Takes the header string and parses out the params needed for a digest authentication.
  72. *
  73. * @param string $header
  74. * @return array
  75. */
  76. public static function decode($header) {
  77. $data = array(
  78. 'realm' => null, 'username' => null, 'uri' => null,
  79. 'nonce' => null, 'opaque' => null, 'qop' => null,
  80. 'cnonce' => null, 'nc' => null,
  81. 'response' => null
  82. );
  83. $keys = implode('|', array_keys($data));
  84. $regex = '@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@';
  85. preg_match_all($regex, $header, $matches, PREG_SET_ORDER);
  86. foreach ($matches as $m) {
  87. if (!isset($m[3]) && !isset($m[4])) {
  88. continue;
  89. }
  90. $data[$m[1]] = $m[3] ? $m[3] : $m[4];
  91. }
  92. return $data;
  93. }
  94. }
  95. ?>