Перейти к основному содержимому

Межсервисная аутентификация и авторизация

В микросервисной архитектуре каждый сервис может выступать в следующих ролях:

  • вызываемый сервис или поставщик API, который защищает свои методы;
  • вызывающий сервис или потребитель API, который вызывает методы других защищенных сервисов.

Эта статья описывает, как настроить безопасное взаимодействие между сервисами.

Защита методов вызываемого сервиса

Чтобы защитить методы вызываемого сервиса:

  1. Включите межсервисную аутентификацию.

    Установите свойство UseIdentityAuthentication в значение true в классе StartParameters.

    Следующий блок кода демонстрирует инициализацию параметров запуска сервиса с включенной аутентификацией.

    StartParameters parameters = new StartParameters()
    {
    UseIdentityAuthentication = true // Включение аутентификации
    };
  2. Защитите методы сервиса с помощью атрибутов.

    После включения аутентификации вы можете контролировать доступ к определенным методам или целым контроллерам с помощью следующих атрибутов:

    • [Authorize]: указывает, что для вызова метода или всех методов контроллера требуется действительный токен доступа.
    • [ScopeRequirement("scope:name")]: указывает, что в токене доступа должна присутствовать определенная область разрешений доступа.

    Следующий блок кода демонстрирует защиту отдельного метода с помощью атрибутов [Authorize] и [ScopeRequirement]. Для вызова метода Greeting потребуется токен с разрешением "myapp:greeting:execute".

    [Authorize] // Требует любой действующий токен
    [ScopeRequirement("myapp:greeting:execute")] // Требует определенное разрешение в токене
    public HelloApiResult Greeting(string name)
    {
    // ... логика метода ...
    }

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

    Следующий блок кода демонстрирует применение атрибута [Authorize] на уровне всего контроллера. Все методы в этом контроллере требуют авторизации, а метод Greeting дополнительно проверяет наличие определенной области разрешений доступа.

    [ApiController]
    [Authorize] // Все методы контроллера требуют авторизации
    public class MyFirstController : ControllerBase
    {
    ...
    [ScopeRequirement("myapp:greeting:execute")] // Для этого метода нужна область разрешений доступа
    public HelloApiResult Greeting(string name)
    {
    // ...
    }
    }
  3. Настройте межсервисное взаимодействие в AdminTools.

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

Вызов методов защищенного сервиса

Если разработанный сервис бизнес-логики обращается к API другого сервиса, который требует авторизации, вам необходимо настроить получение и передачу токена доступа.

Чтобы вызвать методы защищенного сервиса:

  1. Используйте библиотеку ApiClient.

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

    Когда ваш код вызывает метод другого сервиса через APIClient.Proxy, библиотека APIClient выполняет следующую последовательность действий:

    1. Определение области разрешений доступа.

      APIClient на основе атрибутов [ScopeRequirement] на стороне вызываемого сервиса определяет, какая область разрешений доступа требуется для этого метода.

      APIClient проверяет наличие действующего токена доступа с этой областью разрешений доступа в кэше.

    2. Получение токена.

      Если токена доступа нет, APIClient автоматически запрашивает новый токен у сервиса аутентификации и авторизации Identity, используя учетные данные из конфигурации, а именно: ClientId и Secret из appsettings.json. APIClient автоматически находит действующий токен доступа в кэше или запрашивает новый токен доступа у сервиса аутентификации и авторизации Identity.

    3. Выполнение запроса.

      APIClient подставляет полученный токен в заголовок Authorization HTTP-запроса и вызывает целевой метод API.

    4. Возврат результата.

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

  2. Настройте конфигурацию сервиса.

    Для работы APIClient необходимо в конфигурации appsettings.json вашего сервиса указать учетные данные, с которыми ваш сервис будет запрашивать токен доступа у сервиса аутентификации и авторизации Identity.

    Следующий блок кода демонстрирует пример конфигурации для аутентификации по схеме Client Credentials. В секции ClientSelector указывается, какой ClientId использовать для вызова определенного сервиса, а в ClientSecrets хранятся секреты этих клиентов.

    {
    "ApiConfiguration": {
    "IdentityProvider": "local",
    "ClientSelector": [
    {
    "TargetServiceName": "IXyzServiceAsync", // Для вызова сервиса Xyz
    "ClientId": "client-for-xyz" // используется этот клиент
    }
    ],
    "ClientSecrets": [
    {
    "ClientId": "client-for-xyz", // Секрет для клиента 'client-for-xyz'
    "Secret": "your-secret-here"
    }
    ]
    }
    }

    Указанному ClientId должны быть выданы разрешения на вызов целевого API в AdminTools, как описано в пункте 3 инструкции о защите методов вызываемого сервиса.