.NET(非.NET Core)下Sustainsys多SAML2 IDP指定特定IDP发起挑战的实现方法
在.NET Framework中使用Sustainsys.Saml2指定特定IDP发起挑战
针对你的场景,在.NET Framework(非Core)的OWIN环境下,Sustainsys.Saml2没有直接对应Core中Schema的配置项,但可以通过两种方式实现无需手动修改context.Environment就能指定特定IDP发起挑战:
方法1:为每个IDP配置独立的认证类型
这是最接近.NET Core中Schema思路的方案,你可以为每个身份提供商创建单独的Saml2AuthenticationOptions实例,每个实例设置唯一的AuthenticationType,后续发起挑战时直接指定该类型即可。
配置步骤:
- 在
Startup.Auth.cs的ConfigureAuth方法中,为每个IDP单独注册Saml2中间件:
// 第一个IDP配置 var idp1Options = new Saml2AuthenticationOptions("Saml2-IDP1") { SPOptions = new SPOptions { EntityId = new EntityId("https://your-app.com/Saml2") }, SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie }; idp1Options.IdentityProviders.Add( new IdentityProvider( new EntityId("https://idp1.example.com/metadata"), idp1Options.SPOptions) { LoadMetadata = true }); app.UseSaml2Authentication(idp1Options); // 第二个IDP配置 var idp2Options = new Saml2AuthenticationOptions("Saml2-IDP2") { SPOptions = new SPOptions { EntityId = new EntityId("https://your-app.com/Saml2") }, SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie }; idp2Options.IdentityProviders.Add( new IdentityProvider( new EntityId("https://idp2.example.com/metadata"), idp2Options.SPOptions) { LoadMetadata = true }); app.UseSaml2Authentication(idp2Options);
- 发起挑战时,直接指定对应的认证类型:
// 发起IDP1的认证挑战 HttpContext.GetOwinContext().Authentication.Challenge( new AuthenticationProperties { RedirectUri = "/" }, "Saml2-IDP1"); // 发起IDP2的认证挑战 HttpContext.GetOwinContext().Authentication.Challenge( new AuthenticationProperties { RedirectUri = "/" }, "Saml2-IDP2");
这种方式下,每个IDP对应独立的中间件实例,挑战时指定类型即可直接触发对应IDP的认证流程,无需手动操作context.Environment。
方法2:通过AuthenticationProperties传递IDP标识
如果不想为每个IDP注册独立中间件,也可以在发起挑战时,将IDP的EntityId通过AuthenticationProperties传递,然后自定义Saml2中间件的RedirectToIdentityProvider事件来读取该值,自动设置到环境变量中。
实现步骤:
- 在
Startup.Auth.cs中配置通用的Saml2中间件,并注册事件处理:
var saml2Options = new Saml2AuthenticationOptions { SPOptions = new SPOptions { EntityId = new EntityId("https://your-app.com/Saml2") }, SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie }; // 添加所有IDP saml2Options.IdentityProviders.Add( new IdentityProvider(new EntityId("https://idp1.example.com/metadata"), saml2Options.SPOptions) { LoadMetadata = true }); saml2Options.IdentityProviders.Add( new IdentityProvider(new EntityId("https://idp2.example.com/metadata"), saml2Options.SPOptions) { LoadMetadata = true }); // 注册RedirectToIdentityProvider事件,读取传递的IDP标识 saml2Options.Notifications.RedirectToIdentityProvider = context => { if (context.AuthenticationProperties.Dictionary.TryGetValue("Saml2IdpEntityId", out string entityId)) { context.Environment.Add("saml2.idp", new EntityId(entityId)); } return Task.FromResult(0); }; app.UseSaml2Authentication(saml2Options);
- 发起挑战时,在
AuthenticationProperties中传入目标IDP的EntityId:
var props = new AuthenticationProperties { RedirectUri = "/" }; props.Dictionary.Add("Saml2IdpEntityId", "https://idp1.example.com/metadata"); HttpContext.GetOwinContext().Authentication.Challenge(props, Saml2AuthenticationDefaults.AuthenticationType);
这种方式复用单个Saml2中间件,通过事件动态指定要使用的IDP,避免了手动修改环境变量的繁琐操作。
内容的提问来源于stack exchange,提问作者pereceptron
相关产品推荐
相关产品推荐

