IdentityServer4 в качестве клиента WSFederation с предварительным просмотром .Net Core WSFederation2

Я пытаюсь добавить поставщика аутентификации WSFederation в IdentityServer4. Недавно вышел Microsoft.AspNetCore.Authentication.WsFederation Preview 2 был выпущен, и я смог добавить его в обычное приложение Asp.NetCore.

Но мне сложно добавить его в IdentityServer4 EntityFramework-Quickstart Пример.

Вот как я добавил AuthenticationProvider в свой метод Startup.cs / ConfigureServices:

services.AddAuthentication()
                .AddWsFederation("WsFederation", options =>
                {
                    options.Wtrealm = realm;
                    options.MetadataAddress = metadata;
                })

У меня есть кнопка для WSFederation во Frontend, и я также могу войти в систему. Но после обратного вызова я получаю эту ошибку:

InvalidOperationException: отсутствует дополнительное утверждение IdentityServer4.Hosting.IdentityServerAuthenticationService.AssertRequiredClaims (участник ClaimsPrincipal)

Я могу понять, откуда это взялось, это в IdentityServerAuthenticationService.cs IdentityServer4, она ожидает «вспомогательную» претензию - WSFed не возвращает такую ​​претензию:

if (principal.FindFirst(JwtClaimTypes.Subject) == null) throw new InvalidOperationException("sub claim is missing");

Насколько я понимаю, я не могу настроить это утверждение, хотя в проекте быстрого запуска есть некоторые таблицы, которые, кажется, могут быть использованы для этого, особенно те 2:  dbo.IdentityResources-table  dbo.IdentityClaims-table

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

P.S .: Уже есть некоторые вопросы по этой теме, но все они либо до того, как была доступна реализация WSFederation .Net Core, либо относятся к образцу для WSFederation-server, но не для клиента.


person Compufreak    schedule 11.12.2017    source источник
comment
У меня просто возникла идея реализовать что-то вроде настраиваемого поставщика аутентификации, который расширяет аутентификацию WSFederation для преобразования утверждений WSFed (например, upn) в утверждения, совместимые с IdentityProvider (например, sub), но я не уверен, что это будет наиболее элегантным способ. Пытаюсь узнать больше, просматривая исходный код и читая документы.   -  person Compufreak    schedule 11.12.2017


Ответы (2)


Благодаря @leastprivilege я реализовал следующий обходной путь для предоставления подпретензии:

services.AddAuthentication()
                .AddWsFederation("WsFederation", options =>
                {
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    options.Wtrealm = realm;
                    options.MetadataAddress = metadata;
                    options.Events.OnTicketReceived += OnTicketReceived;
                })

/* some more code inbetween */

    /// <summary>
    /// Transform the UPN-claim to the sub-claim to be compatible with IdentityServer4
    /// </summary>
    private async Task OnTicketReceived(TicketReceivedContext ticketReceivedContext)
    {
        var identity = ticketReceivedContext.Principal.Identities.First();
        identity.AddClaim(new Claim("sub", ticketReceivedContext.Principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")));

    }
person Compufreak    schedule 12.12.2017

Вам необходимо выполнить преобразование требований к заявкам, возвращаемым поставщиком WS-Fed. Либо путем обработки событий в самом обработчике WS-Fed, либо с помощью шаблона «ExternalLoginCallback», который используется в пользовательском интерфейсе быстрого запуска:

https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/blob/release/Quickstart/Account/AccountController.cs#L203

person leastprivilege    schedule 11.12.2017
comment
Спасибо - поскольку проверка субтребования выполняется до того, как сработает ExternalLoginCallback, кажется, что единственный вариант без разветвления IdentityServer - выполнить преобразование в самом AuthenticationHandler, поскольку он должен быть выполнен до ExternalLoginCallback. Я попробую и доложу. - person Compufreak; 11.12.2017
comment
Я реализовал OnTicketReceived-Eventhandler, добавив новый идентификатор во вложенное утверждение. Я добавил код внизу своего вопроса - если вы считаете, что это подходящее решение, не стесняйтесь добавлять код к своему ответу, чтобы я мог отметить его как решенный. - person Compufreak; 11.12.2017
comment
ExternalLoginCallback не является частью кодовой базы IdentityServer. Это в пользовательском интерфейсе. Так что все, что вам больше нравится. - person leastprivilege; 11.12.2017
comment
Время, когда срабатывает UI-код, слишком поздно, поскольку проверочный код от IdentityServer запускается до того, как UI-код будет выполнен. Вот почему я не могу поместить туда трансформацию. Теперь я столкнулся с другой проблемой: для каждого принципала разрешено только одно удостоверение, поэтому добавление другого удостоверения с дополнительным требованием тоже не работает. Я не смог найти сеттер для управления утверждениями существующего принципала: // РЕДАКТИРОВАТЬ: Кажется, я могу установить самого принципала - я попробую. - person Compufreak; 12.12.2017
comment
Ой, извините, вы правы - он входит в код IdentityServer в вызове HttpContext.AuthenticateAsync из ExternalLoginCallback. Спасибо за ваше терпение :) - person Compufreak; 12.12.2017