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

时间:2018-10-24 06:36:23

标签: saml identityserver4 component-space

我正在使用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;
                };
            });

2 个答案:

答案 0 :(得分:1)

request参数是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();
});

答案 1 :(得分: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;
                };
            });