Я использую IdentityServer4 с двумя внешними Idp, один с WSFederation (ADFS), а другой с SAML.

Для реализации SAML я использую коммерческий продукт ComponentSpace SAML 2 для ASP.Net Core. Я использую конфигурацию на основе промежуточного программного обеспечения.

Ведение журнала с помощью обоих Idp работает отлично, но теперь у меня есть ситуация, когда, в зависимости от клиента, мне нужно передать дополнительные параметры SAML AuthnRequest. Я знаю, как передать этот дополнительный параметр в запросе (я могу использовать OnAuthnRequestCreated из промежуточного программного обеспечения), но я не знаю, как тестировать в той точке, откуда приходит запрос, то есть от какого клиента.

У меня есть контроль над клиентом, поэтому я также могу передать дополнительные значения acr_values (которые, как мне кажется, можно использовать для передачи пользовательских данных), но опять же я не знаю, как получить их в событии OnAuthnRequestCreated, как показано в приведенном ниже коде.

Любая помощь была бы очень признательна.

services.AddSaml(Configuration.GetSection("SAML"));

services.AddAuthentication()
            .AddWsFederation("adfs", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                //...rest of config (SSO is working)
            })
            .AddSaml("saml", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                //...rest of config (SSO is working)

                options.OnAuthnRequestCreated = request =>
                {                      
                    //Here I would need to know from which client the request is coming (either by client name or url or acr_values or whatever)
                    //to be able to perform conditional logic. I've checked on the request object itself but the info is not in there

                    return request;
                };
            });
0
tjeuten 24 Окт 2018 в 09:36

2 ответа

Лучший ответ

Спасибо ComponentSpace за ответ. Мне не удалось заставить его работать напрямую с вашим решением с помощью app.Use ((context, next)) => ... но ваш комментарий к GetRequiredService указал мне направление, в котором я могу найти решение, как показано ниже. В основном я получаю IHttpContextAccessor, который затем могу использовать для анализа строки запроса. Затем я получаю ReturnUrl из этой строки запроса и использую IIdentityServerInteractionService для получения объекта AuthorizationContext, который содержит то, что мне нужно для построения моей собственной логики.

Так что еще раз спасибо за то, что указали мне правильное направление.

//build and intermediate service provider so we can get already configured services further down this method
var sp = services.BuildServiceProvider();

services.AddAuthentication()
            .AddSaml("SamlIdp", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                options.OnAuthnRequestCreated = request =>
                {
                    var httpContextAccessor = sp.GetService<IHttpContextAccessor>();
                    var queryStringValues = HttpUtility.ParseQueryString(httpContextAccessor.HttpContext.Request.QueryString.Value);

                    var interactionService = sp.GetService<IIdentityServerInteractionService>();
                    var authContext = interactionService.GetAuthorizationContextAsync(queryStringValues["ReturnUrl"]).Result;

                    //authContext now contains client info and other useful stuff to help build further logic to customize the request

                    return request;
                };
            });
0
tjeuten 29 Окт 2018 в 08:56

Параметр запроса - это объект SAML AuthnRequest. Он не включает информацию о клиенте и т. Д.

Вместо события OnAuthnRequestCreated в своем классе Startup вы можете добавить промежуточное ПО, как показано ниже. Вы можете вызвать GetRequiredService для доступа к любым дополнительным интерфейсам (например, IHttpContextAccessor), необходимым для получения информации о клиенте.

app.Use((context, next) =>
{
    var samlServiceProvider =
        context.RequestServices.GetRequiredService<ISamlServiceProvider>();

    samlServiceProvider.OnAuthnRequestCreated += authnRequest =>
    {
        // Update authn request as required.

        return authnRequest;
    };

    return next();
});
1
ComponentSpace 25 Окт 2018 в 00:54
52962388