0

我将 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;
                };
            });
4

2 回答 2

1

请求参数是 SAML AuthnRequest 对象。它不包括客户信息等。

您可以在 Startup 类中添加一些中间件,而不是 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();
});
于 2018-10-25T00:54:13.577 回答
0

感谢 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;
                };
            });
于 2018-10-29T08:56:43.847 回答