ResourceController.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace OAuth2\Controller;
  3. use OAuth2\TokenType\TokenTypeInterface;
  4. use OAuth2\Storage\AccessTokenInterface;
  5. use OAuth2\ScopeInterface;
  6. use OAuth2\RequestInterface;
  7. use OAuth2\ResponseInterface;
  8. use OAuth2\Scope;
  9. /**
  10. * @see OAuth2\Controller\ResourceControllerInterface
  11. */
  12. class ResourceController implements ResourceControllerInterface
  13. {
  14. private $token;
  15. protected $tokenType;
  16. protected $tokenStorage;
  17. protected $config;
  18. protected $scopeUtil;
  19. public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ScopeInterface $scopeUtil = null)
  20. {
  21. $this->tokenType = $tokenType;
  22. $this->tokenStorage = $tokenStorage;
  23. $this->config = array_merge(array(
  24. 'www_realm' => 'Service',
  25. ), $config);
  26. if (is_null($scopeUtil)) {
  27. $scopeUtil = new Scope();
  28. }
  29. $this->scopeUtil = $scopeUtil;
  30. }
  31. public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null)
  32. {
  33. $token = $this->getAccessTokenData($request, $response);
  34. // Check if we have token data
  35. if (is_null($token)) {
  36. return false;
  37. }
  38. /**
  39. * Check scope, if provided
  40. * If token doesn't have a scope, it's null/empty, or it's insufficient, then throw 403
  41. * @see http://tools.ietf.org/html/rfc6750#section-3.1
  42. */
  43. if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) {
  44. $response->setError(403, 'insufficient_scope', 'The request requires higher privileges than provided by the access token');
  45. $response->addHttpHeaders(array(
  46. 'WWW-Authenticate' => sprintf('%s realm="%s", scope="%s", error="%s", error_description="%s"',
  47. $this->tokenType->getTokenType(),
  48. $this->config['www_realm'],
  49. $scope,
  50. $response->getParameter('error'),
  51. $response->getParameter('error_description')
  52. )
  53. ));
  54. return false;
  55. }
  56. // allow retrieval of the token
  57. $this->token = $token;
  58. return (bool) $token;
  59. }
  60. public function getAccessTokenData(RequestInterface $request, ResponseInterface $response)
  61. {
  62. // Get the token parameter
  63. if ($token_param = $this->tokenType->getAccessTokenParameter($request, $response)) {
  64. // Get the stored token data (from the implementing subclass)
  65. // Check we have a well formed token
  66. // Check token expiration (expires is a mandatory paramter)
  67. if (!$token = $this->tokenStorage->getAccessToken($token_param)) {
  68. $response->setError(401, 'invalid_token', 'The access token provided is invalid');
  69. } elseif (!isset($token["expires"]) || !isset($token["client_id"])) {
  70. $response->setError(401, 'malformed_token', 'Malformed token (missing "expires")');
  71. } elseif (time() > $token["expires"]) {
  72. $response->setError(401, 'invalid_token', 'The access token provided has expired');
  73. } else {
  74. return $token;
  75. }
  76. }
  77. $authHeader = sprintf('%s realm="%s"', $this->tokenType->getTokenType(), $this->config['www_realm']);
  78. if ($error = $response->getParameter('error')) {
  79. $authHeader = sprintf('%s, error="%s"', $authHeader, $error);
  80. if ($error_description = $response->getParameter('error_description')) {
  81. $authHeader = sprintf('%s, error_description="%s"', $authHeader, $error_description);
  82. }
  83. }
  84. $response->addHttpHeaders(array('WWW-Authenticate' => $authHeader));
  85. return null;
  86. }
  87. // convenience method to allow retrieval of the token
  88. public function getToken()
  89. {
  90. return $this->token;
  91. }
  92. }