Рейтинг:2

AccessDeniedHttpException на маршруте с _access: TRUE

флаг iq

В моем пользовательском модуле у меня есть несколько маршрутов «публикации», которые не требуют какой-либо аутентификации. Несколько месяцев назад я узнал, что могу добиться этого со следующими требованиями в routing.yml:

мой_модуль.myroute:
  [...]
  требования:
    _access: 'ИСТИНА'

Это работает на моих существующих маршрутах.

Теперь я пытаюсь добавить новый, который анализирует Авторизация HTTP-заголовок только для идентификации: цель состоит в том, чтобы показать пользовательский вид на публичный данные без какой-либо аутентификации или авторизации. Итак, я попытался добраться до своего пользовательского маршрута, добавив Авторизация заголовок (через расширение браузера), и я получаю следующую ошибку:

Путь: /CLS/it/pub/quadroxml. Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: 
Используемый метод аутентификации не разрешен на этом маршруте. 
в Drupal\Core\EventSubscriber\AuthenticationSubscriber->onExceptionAccessDenied() 
(строка 134 [...]/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php).

Таким образом, отправив Авторизация заголовок, по-видимому, запускает какой-то метод аутентификации даже на маршрутах с _access: 'ИСТИНА'.

Могу ли я отключить полностью вся аутентификация и авторизация на некоторых маршрутах? В качестве альтернативы, могу ли я включить «используемый метод аутентификации» на моем маршруте, а затем принять любой пароль? (Меня интересует только идентификатор пользователя!)

Рейтинг:1
флаг cn

Я не уверен, как принять любой пароль. Но есть разница между аутентификацией пользователя по умолчанию и basic_auth вы, вероятно, используете для этого маршрута. Первый определяется как глобальный:

ядро/модули/пользователь/user.services.yml

user.authentication.cookie:
    класс: Drupal\user\Authentication\Provider\Cookie
    аргументы: ['@session_configuration', '@database', '@messenger']
    теги:
      - {имя: authentication_provider, provider_id: 'cookie', приоритет: 0, глобальный: TRUE}

а второй нет:

ядро/модули/basic_auth/basic_auth.services.yml

Сервисы:
  basic_auth.authentication.basic_auth:
    класс: Drupal\basic_auth\Authentication\Provider\BasicAuth
    аргументы: ['@config.factory', '@user.auth', '@flood', '@entity_type.manager']
    теги:
      - {имя: authentication_provider, provider_id: 'basic_auth', приоритет: 100}

В этом случае маршрут должен указывать _auth вариант. Видеть

https://www.drupal.org/docs/drupal-apis/routing-system/structure-of-routes

Francesco Marchetti-Stasi avatar
флаг iq
Что ж, это действительно не все, но это навело меня на правильный путь. Я понял, что доступные провайдеры аутентификации не подходят для моих нужд, поэтому я реализовал собственный. а затем я добавил его к опции `_auth`, как я и предлагал. Я думаю, что это может заслуживать нового ответа и комментария к другому вопросу, который поставил меня на правильный путь...
4uk4 avatar
флаг cn
Я не решался предложить собственного поставщика аутентификации, потому что темой вопроса было определение маршрута. Но показ двух основных определений указывал в этом направлении, и тогда, конечно, вам нужен приоритет> 100, чтобы переопределить оба.
Francesco Marchetti-Stasi avatar
флаг iq
Да, действительно, оно указывало в правильном направлении. Мне любопытно ваше заявление о приоритете, возможно ли, что если я использую низкий приоритет, предопределенные поставщики аутентификации все еще используются? Я спрашиваю, потому что, кажется, это то, что происходит...
4uk4 avatar
флаг cn
Если вы включили базовую аутентификацию HTTP и отправляете заголовок авторизации, этот модуль используется, если только вы не реализуете настраиваемого поставщика аутентификации с более высоким приоритетом. Аутентификация происходит до маршрутизации. После маршрутизации проверяется только, подходит ли провайдер, выигравший гонку аутентификации, для маршрута.
Francesco Marchetti-Stasi avatar
флаг iq
Я понимаю. Это объясняет все, что я видел.Я нигде не нашел такого поведения, задокументированного, но, возможно, я не искал достаточно глубоко. Кроме того, я предполагаю, что реализация пользовательского поведения для базовой HTTP-аутентификации на самом деле не является распространенным требованием, особенно в настоящее время... В любом случае, я думаю, что _теперь_ это задокументировано, _здесь_ :)
Рейтинг:0
флаг bd

Когда дело доходит до управления доступом, вы можете делать практически все, что захотите, либо определив пользовательскую проверку доступа через класс контроллера (1), который вы устанавливаете непосредственно на конкретном маршруте, либо создав собственную службу проверки доступа (2).

1. Проверка доступа через класс контроллера
Документы: Проверка доступа к пользовательскому маршруту

пример.routing.yml

пример:
  [...]
  требования:
    _custom_access: '\Drupal\example\Controller\ExampleController::access'

ПримерКонтроллер.php

класс ПримерКонтроллер {

  доступ к общедоступной функции (AccountInterface $account) {
    // Возврат \Drupal\Core\Access\AccessResultInterface здесь
  }

}

2. Сервис проверки доступа
Документы: Расширенная проверка доступа к маршруту

По сути, вы делаете то же самое, что обеспечивает _доступ параметр, который вы уже используете (который реализуется Проверка доступа по умолчанию. Таким образом, вы создаете помеченный сервис и устанавливаете этот сервис как требование на вашем маршруте. Пример из документации очень полный, поэтому я не копирую его сюда.

Francesco Marchetti-Stasi avatar
флаг iq
Спасибо, я уже добавляю в свой модуль собственную проверку доступа к маршруту. Я попытался добавить еще один для этого нового пути, но это не имело значения: в конце концов мне удалось решить свою проблему с помощью пользовательского поставщика аутентификации, поэтому я думаю, что моя проблема была на более ранней стадии аутентификации, а не в проверке доступа фаза.
Рейтинг:0
флаг iq

Вдохновленный ответом @4k4, я реализовал собственного поставщика аутентификации, как подробно описано здесь: пример реализации, используемый на этой странице, проверяет только наличие заголовка, мне просто пришлось заменить X-Auth-токен с Авторизация чтобы получить код, чтобы делать то, что мне нужно.

С небольшой, но важной поправкой: если я уйду приоритет: 10 в тегах службы аутентификации я еще продолжайте получать ту же ошибку, когда я отправляю Авторизация заголовок в запросе. Я бился над этой проблемой несколько часов, гуглил и искал; в итоге мой взгляд упал на приоритет: -10 значение службы обработки пути, которую я внедрил несколько месяцев назад, где я оставил полезный комментарий «Низкий приоритет действует последним», поэтому я изменил значение приоритета на 1000, и внезапно мне удалось заставить мой маршрут работать!

Я точно не понимаю, почему это происходит, так как у меня был только мой собственный поставщик аутентификации в _auth вектор под параметры, поэтому я не понимаю, как другой провайдер может получить более высокий приоритет. Думаю может это баг, попробую найти время воспроизвести на чистой установке и запилить.

Всем, кому нужна помощь по этому вопросу, также следует взглянуть на этот вопрос: мне не сильно помогло так как проблема с приоритетом не упоминается, но так как проблема точно такая же, может и другие подсказки можно собрать.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.