gpt4 book ai didi

sustainsys-saml2 - Sustainsys.SAML2 与 Multi-Tenancy 应用程序

转载 作者:行者123 更新时间:2023-12-04 17:09:33 34 4
gpt4 key购买 nike

我正在开发一个 Blazor 应用程序,它是一个 Multi-Tenancy 应用程序。
我正在使用 Sustainsys.Saml2.AspNetCore2 包。
我有一个正在运行的测试 Blazor 应用程序,它可以针对测试进行授权 https://stubidp.sustainsys.com IdP 或测试 OKTA IdP 帐户。到目前为止一切都很好!
我想获得一个能够同时使用两个 IdP 的代码示例。我不确定如何通过 services.AddAuthentication().AddSaml2(options => 或其他方式配置 2 个 IdP。我知道如何配置一个但不超过一个。
这将帮助我了解如何为我们的 Multi-Tenancy 应用程序设置不同的 IdP。
我的后续问题是是否可以在运行时将 IdP 添加到我的应用程序中,而不是在应用程序启动并运行 startup.cs 时。
谢谢!

最佳答案

经过大量挖掘,我找到了我问题的答案。将来我将在 GitHub 上发布一个完整的 Blazor 和 WebForms 测试应用程序,但就目前而言,这里有一些关键信息。
创建 Blazor 应用程序时,请确保您允许使用个人用户帐户登录,以获得登录和外部登录 (Saml) 的正确脚手架。如果您当前的 Blazor 应用程序没有身份脚手架,请按照在线步骤将脚手架添加到您的应用程序。
在 Blazor 中,如果您希望每个 IdP 拥有单独的 SAML 模块,您将多次调用 .AddSaml2 并为每个 .AddSaml2 分配一个 IdP (options.IdentityProviders.Add...)。此配置的关键是在构造函数中命名每个 Saml2 提供程序,例如 .AddSaml2("Client1", "Client1", options => 和 .AddSaml2("Client2", "Client2", options =>。当你这样做时,您将看到这些模块名称中的每一个都显示为右侧登录页面上的按钮。
如果您希望在一个模块中包含多个 IdP,那么您可以使用如下配置调用 .AddSaml2 一次:

            // OKTA example that works
//options.SPOptions.EntityId = new EntityId("https://localhost:44312/Okta"); // MSJ - Change to the current URL (proper port) -https://localhost:44312/Saml2
options.SPOptions.EntityId = new EntityId("https://example.com/"); // Dummy entry
// options.SPOptions.ModulePath = "/Okta"; // Don't need this, default is "Saml2"
options.SPOptions.ReturnUrl = new Uri("/counter", UriKind.Relative); // Note used if RelayStateUsedAsReturnUrl set below is true
options.Notifications.AcsCommandResultCreated = AcsCommandResultCreated; // Needed to intercept the command and add the LoginProvider for the tenant if IdP initiated login
options.Notifications.GetIdentityProvider = GetIdentityProvider;
options.Notifications.SelectIdentityProvider = SelectIdentityProvider;
//options.Notifications.MetadataCreated = MetadataCreated;
options.Notifications.AuthenticationRequestCreated = AuthenticationRequestCreated;
options.Notifications.Unsafe.TokenValidationParametersCreated = TokenValidationParametersCreated;
options.SPOptions.ServiceCertificates.Add(new X509Certificate2("Sustainsys.Saml2.Tests.pfx", "")); // Sustainsys.Saml2.Tests.pfx - no password on this pfx file
// For now, turned off Assertion encryption


options.IdentityProviders.Add(new IdentityProvider(new EntityId("http://www.okta.com/exk2edycw57Obmc5i5d7"), options.SPOptions)
{
MetadataLocation = "https://dev-60124262.okta.com/app/exk2edycw57Obmc5i5d7/sso/saml/metadata", // Need this since EntityID is different than metadata location
LoadMetadata = true,
AllowUnsolicitedAuthnResponse = true, // Need this for IdP initiated login

// Need this as well for IdP initiated login to tell SAML2 to redirect to the ExternalLogin page in the Account folder
RelayStateUsedAsReturnUrl = true, // In OKTA or others, ensure the relay state is set to /Identity/Account/ExternalLogin?returnUrl=%2F&handler=Callback to ensure proper routing
});

options.IdentityProviders.Add(new IdentityProvider(
new EntityId("https://stubidp.sustainsys.com/Metadata"), options.SPOptions)
{
LoadMetadata = true,
AllowUnsolicitedAuthnResponse = true,
RelayStateUsedAsReturnUrl = true, // Setting this always gives an error that the ReturnURL is not relative
});
//idp.SigningKeys.AddConfiguredKey(new X509Certificate2("okta.cert")); // Not needed since the cert is in the meta data.

saml2Options = options; // External reference for the options object
我在 Multi-Tenancy 环境中工作,所以我需要做更多的事情(处理通知)才能使事情正常进行。如果您只有一个 IdP,则不需要做这些额外的事情,因为它会正常工作。请注意,我计划动态加载这些 IdP,以便它们不会像本示例中提到的那样存在。这就是为什么我有“saml2Options”对象引用的原因,以便我可以稍后添加 IdP。
Multi-Tenancy 通知代码:
    private void TokenValidationParametersCreated(TokenValidationParameters validationParameters, IdentityProvider idp, XmlElement xmlElement)
{
// ** Will need to replace the URL with the subdomain tenant code
// How do we get access to the Navigation Manager
validationParameters.ValidAudience = "https://localhost:44312/Saml2"; // Was /Okta
// validationParameters.ValidateAudience = false; // Could use this but set the ValidAudience
}

private void AuthenticationRequestCreated(Saml2AuthenticationRequest request, IdentityProvider a, IDictionary<string, string> dict)
{
// This does not seem to matter
// ** Will need to replace the URL with the subdomain tenant code
request.Issuer = new EntityId($"https://localhost:44312/Saml2"); // Was /Okta
}

private void MetadataCreated(EntityDescriptor request, Saml2Urls urls)
{
// ** Will need to replace the URL with the subdomain tenant code
// Not seeing this get called - do not worry about it
request.EntityId = new EntityId($"https://localhost:44312/Saml2");
}

private IdentityProvider SelectIdentityProvider(EntityId entityID, IDictionary<string, string> arg2)
{
return saml2Options.IdentityProviders[entityID];
}

private IdentityProvider GetIdentityProvider(EntityId entityID, IDictionary<string, string> arg2, IOptions arg3)
{

return saml2Options.IdentityProviders[entityID];
}


public void AcsCommandResultCreated(CommandResult arg1, Saml2Response arg2)
{
if (arg1.RelayData == null)
{
// Need to do this for IdP initiated logins. RelayData is null so we need to add the LoginProvider
var x = new Dictionary<string, string>();
x.Add("LoginProvider", "Saml2"); // Will always be "Saml2" if we stick with one Saml endpoint with multiple IdentityProviders
arg1.RelayData = x;
}
}
请注意,要使 IdP 启动登录工作,我需要将其放在 IdP 的 RelayState 中:
/Identity/Account/ExternalLogin?returnUrl=%2F&handler=Callback
最后一个魔法是将 ExternalLogin.cshtml.cs 中的 OnPost 方法更改为:
    public IActionResult OnPost(string provider, string returnUrl = null)
{
// This is used for SP initiated login. So for this case, we know the URL and thus the tenantCode
// Hard coded here for testing but extract the tenant code from the URL here or from the external login button on the
// login page (pass it in)
// We are assuming one scheme (SSO provider) per tenant
string tenantCode = "Dev";
// Request a redirect to the external login provider.
var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl, tenantCode });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);

// This is what they were talking about - add idp and scheme and THEN you will get the proper entityID in SelectIdentityProvider
properties.Items.Add("idp", "http://www.okta.com/exk2edycw57Obmc5i5d7"); // Put in the actual idp EntityID here - hardcoded here for testing
properties.Items.Add("scheme", "Saml2");
properties.Items.Add("tenant", "localhost"); // Used in notifications
return new ChallengeResult(provider, properties);
}
添加“idp”和“scheme”是必须的,以允许通知报告 Multi-Tenancy 环境中使用的实际 IdP。同样,如果您只需要处理一个 IdP,则无需执行所有这些操作。
在 Blazor 中清理完所有内容后,我需要在 WebForms 中的旧版本应用程序中实现相同的内容。乐趣!

关于sustainsys-saml2 - Sustainsys.SAML2 与 Multi-Tenancy 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69776923/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com