HttpBasic.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. namespace OAuth2\ClientAssertionType;
  3. use OAuth2\Storage\ClientCredentialsInterface;
  4. use OAuth2\RequestInterface;
  5. use OAuth2\ResponseInterface;
  6. /**
  7. * Validate a client via Http Basic authentication
  8. *
  9. * @author Brent Shaffer <bshafs at gmail dot com>
  10. */
  11. class HttpBasic implements ClientAssertionTypeInterface
  12. {
  13. private $clientData;
  14. protected $storage;
  15. protected $config;
  16. /**
  17. * @param OAuth2\Storage\ClientCredentialsInterface $clientStorage REQUIRED Storage class for retrieving client credentials information
  18. * @param array $config OPTIONAL Configuration options for the server
  19. * <code>
  20. * $config = array(
  21. * 'allow_credentials_in_request_body' => true, // whether to look for credentials in the POST body in addition to the Authorize HTTP Header
  22. * 'allow_public_clients' => true // if true, "public clients" (clients without a secret) may be authenticated
  23. * );
  24. * </code>
  25. */
  26. public function __construct(ClientCredentialsInterface $storage, array $config = array())
  27. {
  28. $this->storage = $storage;
  29. $this->config = array_merge(array(
  30. 'allow_credentials_in_request_body' => true,
  31. 'allow_public_clients' => true,
  32. ), $config);
  33. }
  34. public function validateRequest(RequestInterface $request, ResponseInterface $response)
  35. {
  36. if (!$clientData = $this->getClientCredentials($request, $response)) {
  37. return false;
  38. }
  39. if (!isset($clientData['client_id'])) {
  40. throw new \LogicException('the clientData array must have "client_id" set');
  41. }
  42. if (!isset($clientData['client_secret']) || $clientData['client_secret'] == '') {
  43. if (!$this->config['allow_public_clients']) {
  44. $response->setError(400, 'invalid_client', 'client credentials are required');
  45. return false;
  46. }
  47. if (!$this->storage->isPublicClient($clientData['client_id'])) {
  48. $response->setError(400, 'invalid_client', 'This client is invalid or must authenticate using a client secret');
  49. return false;
  50. }
  51. } elseif ($this->storage->checkClientCredentials($clientData['client_id'], $clientData['client_secret']) === false) {
  52. $response->setError(400, 'invalid_client', 'The client credentials are invalid');
  53. return false;
  54. }
  55. $this->clientData = $clientData;
  56. return true;
  57. }
  58. public function getClientId()
  59. {
  60. return $this->clientData['client_id'];
  61. }
  62. /**
  63. * Internal function used to get the client credentials from HTTP basic
  64. * auth or POST data.
  65. *
  66. * According to the spec (draft 20), the client_id can be provided in
  67. * the Basic Authorization header (recommended) or via GET/POST.
  68. *
  69. * @return
  70. * A list containing the client identifier and password, for example
  71. * @code
  72. * return array(
  73. * "client_id" => CLIENT_ID, // REQUIRED the client id
  74. * "client_secret" => CLIENT_SECRET, // OPTIONAL the client secret (may be omitted for public clients)
  75. * );
  76. * @endcode
  77. *
  78. * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
  79. *
  80. * @ingroup oauth2_section_2
  81. */
  82. public function getClientCredentials(RequestInterface $request, ResponseInterface $response = null)
  83. {
  84. if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
  85. return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
  86. }
  87. if ($this->config['allow_credentials_in_request_body']) {
  88. // Using POST for HttpBasic authorization is not recommended, but is supported by specification
  89. if (!is_null($request->request('client_id'))) {
  90. /**
  91. * client_secret can be null if the client's password is an empty string
  92. * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
  93. */
  94. return array('client_id' => $request->request('client_id'), 'client_secret' => $request->request('client_secret'));
  95. }
  96. }
  97. if ($response) {
  98. $message = $this->config['allow_credentials_in_request_body'] ? ' or body' : '';
  99. $response->setError(400, 'invalid_client', 'Client credentials were not found in the headers'.$message);
  100. }
  101. return null;
  102. }
  103. }