Укажите схему аутентификации JWT для каждого запроса - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть веб-приложение, которое реализует аутентификацию на основе 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 (), поэтому другой вызов является избыточным.

1 Ответ

0 голосов
/ 24 февраля 2020

Как подсказывает @juunas, вы можете выбрать схему, которую вы хотите аутентифицировать, динамически основываясь на элементах httpcontext:

app.Use(async (context, next) =>
{
    var host = context.Request.Host.ToString();
    if (true)
    {
        var result = await context.AuthenticateAsync("YourScheme");
        if (!result.Succeeded)
        {
            context.Response.StatusCode = 401;  
            return;
        }

    }
    ....

    await next();
});

Вы также можете создать собственный обработчик аутентификации для чтения запроса, проверить использование токена JwtSecurityTokenHandler и, наконец, войдите в систему, используя cook ie аутентификацию .

...