Issue #2054187 by juampy: Restrict authentication provider for REST resources.

8.0.x
Alex Pott 2013-08-13 16:12:48 -05:00
parent 4ca797aa8c
commit 2cfbc1835d
4 changed files with 129 additions and 1 deletions

View File

@ -14,3 +14,13 @@ resources:
# GET:
# supported_formats:
# - json
#
# To enable only specific authentication methods for an operation, list them
# at supported_auth.
# For example, the following config only allows Basic HTTP authenticated
# requests for the POST method on the node entity.
# resources:
# entity:node:
# POST:
# supported_auth:
# - http_basic

View File

@ -72,6 +72,11 @@ class RouteSubscriber implements EventSubscriberInterface {
$collection->add("rest.$name", $route);
continue;
}
// Check if there are authentication provider restrictions in the
// configuration and apply them to the route.
if (is_array($enabled_methods[$method]['supported_auth']) && !empty($enabled_methods[$method]['supported_auth'])) {
$route->setOption('_auth', $enabled_methods[$method]['supported_auth']);
}
// If there is no format requirement or if it matches the
// configuration also add the route.
$format_requirement = $route->getRequirement('_format');

View File

@ -0,0 +1,107 @@
<?php
/**
* @file
* Definition of Drupal\rest\test\AuthTest.
*/
namespace Drupal\rest\Tests;
use Drupal\rest\Tests\RESTTestBase;
/**
* Tests authenticated operations on test entities.
*/
class AuthTest extends RESTTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('hal', 'rest', 'entity_test');
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Resource authentication',
'description' => 'Tests authentication provider restrictions.',
'group' => 'REST',
);
}
/**
* Tests reading from an authenticated resource.
*/
public function testRead() {
$entity_type = 'entity_test';
// Enable a test resource through GET method and basic HTTP authentication.
$this->enableService('entity:' . $entity_type, 'GET', NULL, array('http_basic'));
// Create an entity programmatically.
$entity = $this->entityCreate($entity_type);
$entity->save();
// Try to read the resource as an anonymous user, which should not work.
$response = $this->httpRequest('entity/' . $entity_type . '/' . $entity->id(), 'GET', NULL, $this->defaultMimeType);
$this->assertResponse('401', 'HTTP response code is 401 when the request is not authenticated and the user is anonymous.');
$this->assertText('A fatal error occurred: No authentication credentials provided.');
// Create a user account that has the required permissions to read
// resources via the REST API, but the request is authenticated
// with session cookies.
$permissions = $this->entityPermissions($entity_type, 'view');
$permissions[] = 'restful get entity:' . $entity_type;
$account = $this->drupalCreateUser($permissions);
$this->drupalLogin($account);
// Try to read the resource with session cookie authentication, which is
// not enabled and should not work.
$response = $this->httpRequest('entity/' . $entity_type . '/' . $entity->id(), 'GET', NULL, $this->defaultMimeType);
$this->assertResponse('403', 'HTTP response code is 403 when the request is authenticated but not authorized.');
$this->drupalLogout();
// Now read it with the Basic authentication which is enabled and should
// work.
$response = $this->basicAuthGet('entity/' . $entity_type . '/' . $entity->id(), $account->getUsername(), $account->pass_raw);
$this->assertResponse('200', 'HTTP response code is 200 for successfuly authorized requests.');
$this->curlClose();
}
/**
* Performs a HTTP request with Basic authentication.
*
* We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to
* set curl settings for basic authentication.
*
* @param string $path
* The request path.
* @param string $username
* The user name to authenticate with.
* @param string $password
* The password.
*
* @return string
* Curl output.
*/
protected function basicAuthGet($path, $username, $password) {
$out = $this->curlExec(
array(
CURLOPT_HTTPGET => TRUE,
CURLOPT_URL => url($path, array('absolute' => TRUE)),
CURLOPT_NOBODY => FALSE,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => $username . ':' . $password,
)
);
$this->verbose('GET request to: ' . $path .
'<hr />' . $out);
return $out;
}
}

View File

@ -192,8 +192,10 @@ abstract class RESTTestBase extends WebTestBase {
* The HTTP method to enable, e.g. GET, POST etc.
* @param string $format
* (Optional) The serialization format, e.g. hal_json.
* @param array $auth
* (Optional) The list of valid authentication methods.
*/
protected function enableService($resource_type, $method = 'GET', $format = NULL) {
protected function enableService($resource_type, $method = 'GET', $format = NULL, $auth = array()) {
// Enable REST API for this entity type.
$config = config('rest.settings');
$settings = array();
@ -205,6 +207,10 @@ abstract class RESTTestBase extends WebTestBase {
$settings[$resource_type][$method] = array();
}
}
if (is_array($auth) && !empty($auth)) {
$settings[$resource_type][$method]['supported_auth'] = $auth;
}
$config->set('resources', $settings);
$config->save();