У меня есть веб-приложение, которое реализует аутентификацию на основе Azure B2 C для неограниченного количества арендаторов B2 C. Приложение устанавливает контекст во время выполнения на основе субдомена хоста, который, в свою очередь, выбирает подходящего арендатора.
Это работает достаточно легко на стороне клиента, поскольку приложение запускается только в браузере пользователя в одном контексте в любом данное время. Однако, поскольку существует только один экземпляр уровня API, он должен иметь возможность одновременно поддерживать запросы, поступающие от нескольких разных пользователей, с использованием токенов канала-носителя, выданных несколькими разными арендаторами.
Я использую следующий код для добавления схем аутентификации при запуске для каждого из арендаторов. Имя схемы равно URL исходного контекста:
foreach (Context context in Contexts)
{
services.AddAuthentication()
.AddJwtBearer(context.url,
jwtOptions =>
{
jwtOptions.Authority = context.tenant;
jwtOptions.Audience = context.client;
}
);
}
Мой вопрос: как мне сообщить промежуточному программному обеспечению аутентификации, какую схему использовать, чтобы проверить токен носителя пользователя? Есть ли способ, как это происходит как-то автоматически, или мне вместо этого нужно создать собственный AuthorizeAttribute?
Спасибо!
ОБНОВЛЕНИЕ: я смог заставить это работать, создав и зарегистрировав пользовательский поставщик политики, как указано ниже:
internal class MyCustomPolicyProvider : IAuthorizationPolicyProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyCustomPolicyProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
Uri uri = new Uri(_httpContextAccessor.HttpContext.Request.Headers["Referer"].ToString());
return Task.FromResult(new AuthorizationPolicyBuilder(uri.Host).RequireAuthenticatedUser().Build());
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
Uri uri = new Uri(_httpContextAccessor.HttpContext.Request.Headers["Referer"].ToString());
return Task.FromResult(new AuthorizationPolicyBuilder(uri.Host).RequireAuthenticatedUser().Build());
}
}
Затем контроллеры защищены следующим образом:
[Authorize(Policy = "MyCustom")]
Это выглядит немного неуклюже, но работает. Я не совсем понимаю, почему оба GetPolicyAsyn c () и GetDefaultPolicyAsyn c (), которые требуются IAuthorizationPolicyProvider, запускаются при каждой авторизации. Кажется, нам нужен только GetPolicyAsyn c (), поэтому другой вызов является избыточным.