Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Автор: Майк Роусос (Mike Rousos)
Обычно при использовании авторизации на основе политик политики политики регистрируются путем вызова AuthorizationOptions.AddPolicy
в рамках конфигурации службы авторизации. В некоторых сценариях может быть невозможно (или желательно) зарегистрировать все политики авторизации таким образом. В таких случаях можно использовать пользователь IAuthorizationPolicyProvider
для управления предоставлением политик авторизации.
Примеры сценариев, в которых пользователь IAuthorizationPolicyProvider может оказаться полезным:
- Использование внешней службы для оценки политики.
- Использование большого диапазона политик (для разных номеров или возрастов), поэтому не имеет смысла добавлять каждую отдельную политику авторизации с вызовом
AuthorizationOptions.AddPolicy
. - Создание политик во время выполнения на основе информации во внешнем источнике данных (например, в базе данных) или динамическое определение требований авторизации с помощью другого механизма.
Просмотр или скачивание примера кода из репозитория GitHub AspNetCore. Скачайте ZIP-файл zip-файла репозитория dotnet/AspNetCore. Распакуйте файл . Перейдите в папку проекта src/Security/samples/CustomPolicyProvider .
Настройка извлечения политики
ASP.NET приложения Core используют реализацию IAuthorizationPolicyProvider
интерфейса для получения политик авторизации. По умолчанию DefaultAuthorizationPolicyProvider регистрируется и используется. DefaultAuthorizationPolicyProvider
возвращает политики из предоставленного AuthorizationOptions
в вызове IServiceCollection.AddAuthorization
.
Настройте это поведение, зарегистрируя другую IAuthorizationPolicyProvider
реализацию в контейнере внедрения зависимостей приложения.
Интерфейс IAuthorizationPolicyProvider
содержит три API:
- GetPolicyAsync возвращает политику авторизации для заданного имени.
- GetDefaultPolicyAsync возвращает политику авторизации по умолчанию (политика, используемая для
[Authorize]
атрибутов без указанной политики). - GetFallbackPolicyAsync возвращает резервную политику авторизации (политика, используемая ПО промежуточного слоя авторизации, если политика не указана).
Реализуя эти API, можно настроить способ предоставления политик авторизации.
Пример атрибута параметризованной авторизации
Один из сценариев, где IAuthorizationPolicyProvider
полезно включить пользовательские [Authorize]
атрибуты, требования которых зависят от параметра. Например, в документации по авторизации на основе политик в качестве примера использовалась политика на основе возраста (AtLeast21). Если различные действия контроллера в приложении должны быть доступны пользователям разных возрастов, может быть полезно иметь множество различных политик на основе возраста. Вместо регистрации всех разных политик на основе возраста, которые потребуется AuthorizationOptions
приложению, вы можете динамически создавать политики с помощью пользовательского IAuthorizationPolicyProvider
. Чтобы упростить использование политик, можно произвести анимацию действий с помощью настраиваемого атрибута авторизации, например [MinimumAgeAuthorize(20)]
.
Настраиваемые атрибуты авторизации
Политики авторизации определяются своими именами. Ранее пользовательский пользователь MinimumAgeAuthorizeAttribute
должен сопоставить аргументы с строкой, которую можно использовать для получения соответствующей политики авторизации. Это можно сделать, исходя из AuthorizeAttribute
свойства и делая Age
свойство оболочкой AuthorizeAttribute.Policy
свойства.
internal class MinimumAgeAuthorizeAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "MinimumAge";
public MinimumAgeAuthorizeAttribute(int age) => Age = age;
// Get or set the Age property by manipulating the underlying Policy property
public int Age
{
get
{
if (int.TryParse(Policy.Substring(POLICY_PREFIX.Length), out var age))
{
return age;
}
return default(int);
}
set
{
Policy = $"{POLICY_PREFIX}{value.ToString()}";
}
}
}
Этот тип атрибута имеет Policy
строку на основе жестко закодированного префикса ("MinimumAge"
) и целого числа, переданного через конструктор.
Его можно применить к действиям так же, как и к другим Authorize
атрибутам, за исключением того, что он принимает целое число в качестве параметра.
[MinimumAgeAuthorize(10)]
public IActionResult RequiresMinimumAge10()
Custom IAuthorizationPolicyProvider
Пользователь MinimumAgeAuthorizeAttribute
позволяет легко запрашивать политики авторизации для любого требуемого возраста. Следующая проблема заключается в том, чтобы убедиться, что политики авторизации доступны для всех разных возрастов. Это место, где IAuthorizationPolicyProvider
полезно.
При использовании MinimumAgeAuthorizationAttribute
имена политик авторизации будут соответствовать шаблону "MinimumAge" + Age
, поэтому пользователь IAuthorizationPolicyProvider
должен создавать политики авторизации следующим образом:
- Анализ возраста с имени политики.
- Использование
AuthorizationPolicyBuilder
для создания новогоAuthorizationPolicy
- В этом и следующих примерах предполагается, что пользователь проходит проверку подлинности с помощью .cookie Должен
AuthorizationPolicyBuilder
быть создан по крайней мере с одним именем схемы авторизации или всегда выполнен успешно. В противном случае нет информации о том, как предоставить пользователю вызов, и будет создано исключение. - Добавление требований к политике в зависимости от возраста
AuthorizationPolicyBuilder.AddRequirements
. В других сценариях можно использоватьRequireClaim
илиRequireRole
RequireUserName
вместо этого.
internal class MinimumAgePolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "MinimumAge";
// Policies are looked up by string name, so expect 'parameters' (like age)
// to be embedded in the policy names. This is abstracted away from developers
// by the more strongly-typed attributes derived from AuthorizeAttribute
// (like [MinimumAgeAuthorize()] in this sample)
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase) &&
int.TryParse(policyName.Substring(POLICY_PREFIX.Length), out var age))
{
var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
policy.AddRequirements(new MinimumAgeRequirement(age));
return Task.FromResult(policy.Build());
}
return Task.FromResult<AuthorizationPolicy>(null);
}
}
Несколько поставщиков политик авторизации
При использовании пользовательских IAuthorizationPolicyProvider
реализаций следует учитывать, что ASP.NET Core использует только один экземпляр IAuthorizationPolicyProvider
. Если настраиваемый поставщик не может предоставлять политики авторизации для всех используемых имен политик, он должен отложить поставщику резервных копий.
Например, рассмотрим приложение, которое нуждается как в пользовательских политиках возрастов, так и для получения более традиционных политик на основе ролей. Такое приложение может использовать настраиваемый поставщик политики авторизации, который:
- Пытается проанализировать имена политик.
- Вызывает другой поставщик политик (например
DefaultAuthorizationPolicyProvider
, если имя политики не содержит возраст).
Пример IAuthorizationPolicyProvider
реализации, показанной выше, можно обновить для использования DefaultAuthorizationPolicyProvider
путем создания поставщика политики резервного копирования в его конструкторе (если имя политики не соответствует ожидаемому шаблону "MinimumAge" + возраст).
private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }
public MinimumAgePolicyProvider(IOptions<AuthorizationOptions> options)
{
// ASP.NET Core only uses one authorization policy provider, so if the custom implementation
// doesn't handle all policies it should fall back to an alternate provider.
BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
GetPolicyAsync
Затем метод можно обновить, чтобы использовать BackupPolicyProvider
вместо возвращающего значение NULL:
...
return BackupPolicyProvider.GetPolicyAsync(policyName);
Политика по умолчанию
Помимо предоставления именованных политик авторизации, пользователь IAuthorizationPolicyProvider
должен реализовать GetDefaultPolicyAsync
политику авторизации для [Authorize]
атрибутов без указанного имени политики.
Во многих случаях для этого атрибута авторизации требуется только прошедший проверку подлинности пользователь, поэтому вы можете сделать необходимую политику с помощью вызова RequireAuthenticatedUser
:
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() =>
Task.FromResult(new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build());
Как и во всех аспектах пользовательского IAuthorizationPolicyProvider
, вы можете настроить это, по мере необходимости. В некоторых случаях может потребоваться получить политику по умолчанию из резервной IAuthorizationPolicyProvider
версии.
Резервная политика
Пользователь IAuthorizationPolicyProvider
может при необходимости реализовать GetFallbackPolicyAsync
политику, которая используется при объединении политик и при отсутствии указанных политик. При GetFallbackPolicyAsync
возврате политики, отличной от null, возвращаемая политика используется ПО промежуточного слоя авторизации, если для запроса не указаны политики.
Если резервная политика не требуется, поставщик может вернуть null
или отложить резервный поставщик:
public Task<AuthorizationPolicy> GetFallbackPolicyAsync() =>
Task.FromResult<AuthorizationPolicy>(null);
Использование пользовательского IAuthorizationPolicyProvider
Чтобы использовать пользовательские политики из объектаIAuthorizationPolicyProvider
, необходимо:
Зарегистрируйте соответствующие
AuthorizationHandler
типы с внедрением зависимостей (описано в авторизации на основе политик), как и во всех сценариях авторизации на основе политик.Зарегистрируйте пользовательский
IAuthorizationPolicyProvider
тип в коллекции служб внедрения зависимостей приложения,Startup.ConfigureServices
чтобы заменить поставщика политик по умолчанию.services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
Полный пользовательский IAuthorizationPolicyProvider
пример доступен в репозитории dotnet/aspnetcore GitHub.
ASP.NET Core