Problem/Motivation

In #2286971: Remove dependency of current_user on request and authentication manager the method scope is changed from public to protected

# core/lib/Drupal/Core/Authentication/AuthenticationManager.php:259
  protected function getSortedProviders() {

but https://www.drupal.org/project/restui uses this to configure the rest resources in

# modules/restui/restui.module:37
  $authentication_providers = array_keys(\Drupal::service('authentication')->getSortedProviders());

Proposed resolution

Add a public method AuthenticationManager::getProviderKeys() #5
Create Interface for AuthenticationManager #3

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

clemens.tolboom’s picture

Title: Please revert protect method back to public » Please revert AuthenticationManager protected method back to public
Berdir’s picture

Title: Please revert AuthenticationManager protected method back to public » Revert AuthenticationManager protected method back to public

Hm, is there on other method that can be used?

I guess having a method that returns all providers is useful, not 100% if that is the right one, though.

dawehner’s picture

If we make this method public we should probably add an AuthenticationManagerInterface as well?

An alternative implementation is to provide an alternative service which lets you access to data, which though is not needed on runtime per default,
but this feels too much of an overhead.

Berdir’s picture

If we make it public, then let's also add some unit tests. There's an existing unit test class, see existing examples there on how to set up the authentication manager and add providers, create one with 3 or so providers with different weight, then make sure you get them in the correct order.

clemens.tolboom’s picture

Issue summary: View changes
Status: Needs review » Needs work

Thanks for the quick responses :)

REST UI is only interested in the provider keys to change config for those.

So best options is to just add a public method AuthenticationManager::getProviderKeys() to fix for REST UI [edit]as @dawehner suggest[/edit]. Making it public again is indeed heavier.

If one needs to change a provider there should be other ways to gain access to one.

clemens.tolboom’s picture

Title: Revert AuthenticationManager protected method back to public » AuthenticationManager needs interface and ::getProviderKeys
Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +Contributed project blocker
FileSize
2.79 KB

I've added interface and put two public methods behind it.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
@@ -20,7 +20,7 @@
-class AuthenticationManager implements AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {
+class AuthenticationManager implements AuthenticationManagerInterface, AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {

So shouldn't the authentication manager interface extend all the other ones here?

clemens.tolboom’s picture

@dawehner thanks. That seems logic. I moved the other interfaces around.

interface AuthenticationManagerInterface extends AuthenticationProviderInterface, AuthenticationProviderFilterInterface, AuthenticationProviderChallengeInterface {
znerol’s picture

#2286971: Remove dependency of current_user on request and authentication manager modified AuthenticationSubscriber in a way such that it is possible to use a bare AuthenticationProviderInterface as the authentication service. E.g.

  authentication:
    class: Drupal\basic_auth\Authentication\Provider\BasicAuth

We even could automatically eliminate AuthenticationManager for sites which only use one authentication method, e.g. in #2432585: Improve authentication manager service construction to support custom global service providers. Therefore it should not be assumed that the authentication service actually implements the AuthenticationManagerInterface.

googletorp’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php
@@ -0,0 +1,34 @@
+  /**
+   * List of provider keys.
+   *
+   * @return array
+   */

You need to document the @return

Fx

/**
 * Get the list of provider keys/
 *
 * @return array
 *   The list of provider keys
 */

I know it may seem a bit double, but this is how the coding standards / doxygen is.

clemens.tolboom’s picture

Status: Needs work » Needs review
FileSize
2.83 KB

@znerol thanks for the pointer. I have no clue what to do for this issue. This is a Contributed project blocker for Rest UI #2456283: AuthenticationManager::getSortedProviders is protected

AuthenticationManagerInterface::getProviderKeys gives Rest UI the config keys to setup rest. Is there an alternative to get to the active providers for Rest UI?

@googletorp thanks for the review.

googletorp’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php
@@ -0,0 +1,35 @@
+   *   The list of provider keys

I know it's small stuff, but comments has to end with a "." like in a sentence. You can use a code sniffer to detect this for you.

clemens.tolboom’s picture

Status: Needs work » Needs review
FileSize
2.83 KB

@googletorp hehe ... I just copied over your text line :p

@googletorp is this RTBC now?

googletorp’s picture

Status: Needs review » Reviewed & tested by the community

#13 Yeah, sorry my bad for being in a hurry.

Looks good to me :)

znerol’s picture

Re #11: I think that #2456283: AuthenticationManager::getSortedProviders is protected should not assume that the authentication service always has getProviderKeys.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

How come the rest ui can't just get the authentication providers from the container?
I.e just add

      - { name: service_collector, tag: authentication_provider, call: addProvider }

to your service and implement an add provider method.

znerol’s picture

clemens.tolboom’s picture

Status: Closed (duplicate) » Closed (won't fix)

This is a 'Won't fix' as it is resolved differently both in Core and contrib Rest UI

-enzo-’s picture

Status: Closed (won't fix) » Active
-enzo-’s picture

I am co-maintainer of project Drupal Console (http://drupalconsole.com) and we have the same blocker as REST UI had in the past, Drupal Console used to have a command to enable Rest Resources listing the Authentication methods available to be used by a Rest Resource.

The solution provided by Rest UI module to overwrite the AddProvider function to build a list of Authentication methods available isn't an option for us because Drupal Console is not a module so we can't overwrite the service. For that reason we require a way to get the list of method available.

If there is a security issue in rollback function getSortedProviders to public again, please let me know to consider remove that command from Drupal Console.

clemens.tolboom’s picture

Status: Active » Closed (won't fix)

[edit]Bad reply[/edit]

clemens.tolboom’s picture

Status: Closed (won't fix) » Active

Sorry for my bad reading. @-enzo- has a good point which I missed.

Drupal Console is not a module so we can't overwrite the service.

znerol’s picture

We switched getSortedProviders() in #2286971: Remove dependency of current_user on request and authentication manager to protected because of the following reasons:

The authentication service is only required to implement AuthenticationProviderInterface. Usage of the authentication manager is optional, authentication also works if a site hard-codes the cookie authentication provider into the authentication service. Throughout core there is nothing which desires to access metadata about providers managed by the authentication manager, therefore we concluded that this metadata is private to the manager.

I see that this conclusion is not quite correct. In fact provider keys are kind of shared with the routing system. Also I see that it might be useful for other use-cases to retrieve metadata about the providers if the authentication manager is in use.

However, I do no think that we simply should revert the visibility of getSortedProviders(). Rather let's add a method which returns metadata records keyed by provider key, such that the result looks something like this:

$result = [
  'basic_auth' => [
    'service_id' => 'basic_auth.authentication.basic_auth',
    'priority' => 100,
    'global' => FALSE,
  ],
  'cookie' => [
    'service_id' => 'authentication.cookie',
    'priority' => 0,
    'global' => TRUE,
  ],
];

Another option would be to simply move the provider collector service from the REST UI module to the core REST module. After all it currently looks like this is where that information is needed.

clemens.tolboom’s picture

Another option would be to simply move the provider collector service from the REST UI module to the core REST module. After all it currently looks like this is where that information is needed.

@znerol I think that's a great idea. But is that acceptable by core committers?

clemens.tolboom’s picture

Status: Active » Closed (works as designed)
Parent issue: » #2490228: Add Authentication Collector
Related issues: +#2228141: Add authentication support to REST views

I close this as works as designed and start working on #2490228: Add Authentication Collector

Note this problem is also evident in #2228141: Add authentication support to REST views