Хостинг asp. net core + ReactJS веб-приложение с SSL, содержащим несколько CN или доменных имен, вызывает ошибку неверного эмитента - PullRequest
2 голосов
/ 14 февраля 2020

Я столкнулся со следующей проблемой при размещении веб-приложения, созданного с asp. net core 3.1 и React.

Мы использовали шаблон Visual Studio по умолчанию для React. ASP. NET Идентификация используется для аутентификации и авторизации.

Аутентификация и авторизация работают должным образом, пока мы размещаем веб-сайт с сертификатом SSL, выданным для одного домена или CN. (например, example.com)

Если мы размещаем веб-сайт с SSL с несколькими CN (например, example.com, sub1.example.com, sub2.example.com), отлично работает для любого ОДИН из доменов. Для остальных доменов мы получаем следующее поведение:

Логин работает как положено. Путь / connect / token выдает действительный токен. После входа в систему, когда мы пытаемся вызвать любой API-интерфейс (все API-адреса размещаются в / api route), мы получаем 401 несанкционированную ошибку. Описание ошибки в заголовке:

WWW-Authenticate: ошибка канала-носителя = "invalid_token", error_description = "Эмитент" https://sub1.example.com 'недействителен ".

Я также попытался проанализировать выданный токен на jwt.io. Поле iss (эмитент) - https://sub1.example.com, которое точно соответствует описанию ошибки. Я не могу понять, почему механизм идентификации отказывается идентифицировать эмитента, для которого он выдал токен.

Здесь приведен соответствующий фрагмент из файла Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
    services.AddAuthentication()
            .AddIdentityServerJwt();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseAuthentication();
    app.UseIdentityServer();
    app.UseAuthorization();
}

Есть идеи?

Ответы [ 3 ]

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

Пожалуйста, проверьте URL http: // {url} /.well-known/openid-configuration

Этот URL-адрес должен быть истинным

Следующие коды работают в другом домене. Auth Startup

 services.AddIdentityServer(options =>
        {
            options.IssuerUri = Configuration["ServerSettings:Authority"].ToString();
            options.PublicOrigin = Configuration["ServerSettings:Authority"].ToString();
        })
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients())
            .AddProfileService<ProfileService>();

Api Startup

services.AddAuthentication("Bearer")
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = Configuration["ServerSettings:Authority"].ToString(); //"http://localhost:31864";
            options.RequireHttpsMetadata = false;
            options.ApiName = "api";
        });

Работает в том же домене, но если другой домен, вы должны указать это

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

Новый. Net (. net core) обладает высокой степенью конфигурации и модульности. Обычно методы расширения принимают делегата, который мы можем использовать для настройки параметров. Однако метод AddIdentityServerJwt не следует этому соглашению.

Я давно заметил go, что в TokenValidationParameters есть свойство с именем ValidIssuers, которое можно настроить с помощью метода расширения AddJwtBearer. Однако метод расширения AddIdentityServerJwt не принимает делегатов опций в качестве параметра.

Оказывается, существует специальный способ для настройки опций.

services.AddAuthentication()
    .AddIdentityServerJwt();

services.Configure<JwtBearerOptions>(IdentityServerJwtConstants.IdentityServerJwtBearerScheme, options =>
{
    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
    {
        ValidIssuers = new string[] { "https://sub1.example.com", "https://sub2.example.com", "https://sub3.example.com" }
    };
});

Добавлен этот код и проблема решена. Конфигурацию также можно перенести в настройки приложений. json.

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

Это, вероятно, происходит в результате получения токена от экземпляра IdentityServer4 на одном CN и попытки его проверки с помощью запроса к IdentityServer4 с использованием другого CN. Компонент IdentityServer, который отклоняет токен, является методом ValidateJwtAsyn c TokenValidator. Этот метод передает издателя в ValidateToken JwtSecurityTokenHandler как свойство TokenValidationParameters . Эмитент извлекается либо из источника, настроенного для IdentityServerOptions в методе расширения 'AddIdentityServer', либо динамически генерируется из запроса .

, который я могу себе представить. Один из способов решения проблем проверки - это установка источника для IdentityServerOptions с использованием делегата, переданного в AddIdentityServer . Это приведет к тому, что один и тот же эмитент будет установлен для всех выпущенных токенов, независимо от того, с какого CN был получен доступ. Это предоставит IdentityServer единый источник правды для информации об эмитенте и позволит IdentityServer узнать, с каким эмитентом проверять, когда токен приходит на проверку.

Другие решения, направленные на поддержание эмитента, сильно ограничены TokenValidator является внутренним классом, который не может быть унаследован и легко заменен реализацией, которая будет проверять список допустимых издателей. Кроме того, IdentityServerOptions, для которого настроен uri эмитента, зарегистрирован как одиночный , и его значения не могут быть изменены. Можно было бы придумать другую надуманную реализацию, например, попытаться динамически изменить значение хоста в HttpContext с помощью промежуточного программного обеспечения (что, я не уверен, даже возможно, поскольку я никогда не пробовал), но все, что идет вразрез с конструктивным решением IdentityServer4, не рекомендуется.

...