A REST resource's "auth" configuration MUST be non-empty, which prevents configuring it for anon access only

Created on 13 October 2016, about 8 years ago
Updated 19 June 2023, over 1 year ago

Problem/Motivation

When you want to allow anonymous users to access a REST resource, you need to:

  1. grant the necessary permissions/node grants to the anonymous user role
  2. not list any authentication providers for the REST resource's configuration

And then it should work.

However:

        // Check that authentication providers are defined.
        if (empty($rest_resource_config->getAuthenticationProviders($method))) {
          $this->logger->error('At least one authentication provider must be defined for resource @id', array(':id' => $rest_resource_config->id()));
          continue;
        }

This means that you must specify an authentication provider, otherwise the route won't be created. Then once you have specified e.g. cookie, or basic_auth (or both, or more — as long there is any authentication provider listed), the route will be created. If you then set up your permissions correctly, you'll still be able to use the resource as the anonymous user … due to quirks in how the routing system works.

Small detail: note how the error logging there is broken: @id in the text, but :id in the parameters. Which means the logging is broken.

Fun fact: this implies that \Drupal\user\Plugin\rest\resource\UserRegistrationResource which was added in #2291055: REST resources for anonymous users: register cannot be used at all in practice! (See #27 for details.) This alone is sufficient to make this major.

I'm not convinced, because … how do anonymous REST tests work around this then, if it is so broken?

Glad you asked!

Above, we explained how setting the cookie provider would allow anonymous users to use it. But, alternatively, you must specify the empty string as an authentication provider, i.e.:

supported_auth: ['']

That gets you past the above if-test (because the array is not empty: empty(['']) === FALSE), and hence the route will be created, and it just happens to be that Symfony also doesn't validate this further… This is how NodeJsonAnonTest etc are able to work: because \Drupal\Tests\rest\Functional\ResourceTestBase::$auth === FALSE by default, and \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::provisionEntityResource() does:

$auth = isset(static::$auth) ? [static::$auth] : [];

This results in $auth = [FALSE], which when it is passed to \Drupal\Tests\rest\Functional\ResourceTestBase::provisionResource() and saved into a RestResourceConfig entity just happens to be stored as 'authentication' => ['']… because PHP bool-to-string casting…

(First described in #16.)

Proposed resolution

There are multiple ways to solve this:

Remaining tasks

  1. Decide which solution we want to go with.
  2. Test coverage
  3. Update https://www.drupal.org/docs/8/api/authentication-api

User interface changes

None.

API changes

None.

Data model changes

None.

🐛 Bug report
Status

Needs work

Version

9.5

Component
REST 

Last updated about 1 month ago

Created by

🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

Live updates comments and jobs are added and updated live.
  • Needs documentation

    A documentation change is requested elsewhere. For Drupal core (and possibly other projects), once the change has been committed, this status should be recorded in a change record node.

  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

  • DrupalWTF

    Worse Than Failure. Approximates the unpleasant remark made by Drupal developers when they first encounter a particular (mis)feature.

  • Contributed project blocker

    It denotes an issue that prevents porting of a contributed project to the stable version of Drupal due to missing APIs, regressions, and so on.

  • Security improvements

    It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024