带有 ComponentSpace SAML 2 的 Identityserver4 在请求期间获取自定义参数

Identityserver4 with ComponentSpace SAML 2 get custom parameters during request

我将 IdentityServer4 与两个外部 Idp 一起使用,一个使用 WSFederation (ADFS),另一个使用 SAML。

对于 SAML 实施,我使用商业产品 ComponentSpace SAML 2 for 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;
                };
            });

请求参数为SAML AuthnRequest对象。不包含客户信息等

您可以在 Startup class 中添加一些中间件,而不是 OnAuthnRequestCreated 事件,如下所示。您可以调用 GetRequiredService 来访问您需要检索客户端信息的任何其他接口(例如 IHttpContextAccessor)。

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

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

        return authnRequest;
    };

    return next();
});

感谢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;
                };
            });