You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AuthServices多IdP:如何在ACS与回调Action间传递entityId?

解决方案:在Sustainsys.Saml2中识别用户所属的Identity Provider

我来帮你搞定这个问题!在Sustainsys.Saml2框架里,完全不需要强制IdP发送特殊声明,就能在回调Action里获取到对应的IdP EntityId,这里有几个实用的方法:

方法1:利用框架默认生成的IdentityProvider Claim

Sustainsys.Saml2在处理SAML响应时,会自动把IdP的EntityId添加到用户的Claims集合里,对应的Claim类型是http://schemas.microsoft.com/ws/2008/06/identity/claims/identityprovider。你直接在ExternalLoginCallback里提取就行:

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
    // 获取SAML认证的结果
    var authResult = await HttpContext.AuthenticateAsync(Saml2Defaults.AuthenticationScheme);
    
    if (!authResult.Succeeded)
    {
        // 处理认证失败的逻辑,比如跳回登录页
        return RedirectToAction("Login");
    }

    // 提取IdP的EntityId
    var idpEntityId = authResult.Principal.FindFirstValue("http://schemas.microsoft.com/ws/2008/06/identity/claims/identityprovider");
    
    // 接下来就可以用这个idpEntityId来判断用户属于哪个IdP了
    // ...你的业务逻辑
}

这个方法最省心,完全依赖框架的默认行为,不需要改任何额外配置。

方法2:发起认证时主动传递IdP EntityId

如果想更主动地控制这个值的传递,你可以在触发SAML登录挑战的时候,把IdP的EntityId存入AuthenticationProperties里,之后在回调里取出来:

触发登录的代码(比如用户选择某个IdP后的Action)

public IActionResult LoginWithSpecificIdp(string idpEntityId)
{
    var authProperties = new AuthenticationProperties
    {
        Items = { { "TargetIdpEntityId", idpEntityId } },
        RedirectUri = Url.Action("ExternalLoginCallback")
    };
    
    // 针对指定的IdP发起认证挑战
    return Challenge(authProperties, Saml2Defaults.AuthenticationScheme, idpEntityId);
}

回调Action中提取值

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
    // 获取认证时的属性集合
    var authProperties = await HttpContext.GetAuthenticationAsyncProperties(Saml2Defaults.AuthenticationScheme);
    
    if (authProperties?.Items.TryGetValue("TargetIdpEntityId", out var idpEntityId) == true)
    {
        // 这里就拿到了发起登录时指定的IdP EntityId
        // ...你的验证逻辑
    }
    
    // 后续业务处理
    // ...
}

这种方式适合你需要在发起登录时就明确记录目标IdP的场景,完全可控。

方法3:通过认证事件自定义处理

你还可以借助Sustainsys的Saml2AuthenticationEvents,在认证完成时手动把IdP的EntityId添加到用户Claims或者属性里:

在你的Startup.cs(或者Program.cs)的认证配置里添加这个事件:

services.AddAuthentication()
    .AddSaml2(options =>
    {
        // 这里是你已有的Saml2配置,比如IdP元数据、SP配置等
        // ...
        
        options.Events = new Saml2AuthenticationEvents
        {
            OnAuthenticated = context =>
            {
                // 从SAML响应里直接获取IdP的Issuer(也就是EntityId)
                var idpEntityId = context.Saml2Response.Issuer.Value;
                
                // 可以添加一个自定义Claim,方便后续取用
                context.Principal.AddClaim(new Claim("CustomIdpEntityId", idpEntityId));
                
                // 也可以把值存入AuthenticationProperties
                context.Properties.Items["CustomIdpEntityId"] = idpEntityId;
                
                return Task.CompletedTask;
            }
        };
    });

之后在ExternalLoginCallback里,你就可以通过authResult.Principal.FindFirstValue("CustomIdpEntityId")或者从属性集合里提取这个值了。


内容的提问来源于stack exchange,提问作者sav931

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:55:54