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

Sustainsys.Saml2 IDP发起流访问User.Claims跳转其他IDP问题

异常触发原因
  • 核心配置错误:循环注册多SAML认证方案时,每次调用services.AddAuthentication()都会覆盖全局认证默认配置,最终全局默认的Cookie认证方案为最后一个注册的SAML方案对应的Cookie。
  • 身份匹配失败:IDP发起登录时,当前IDP认证成功后写入的是自身对应名称的Cookie,跳转至GetTokenResponse接口时,全局默认Cookie方案与当前用户持有的Cookie名称不匹配,导致身份认证失败,触发全局挑战逻辑重定向至其他IDP。
  • 环境差异原因:QA环境的IDP配置列表顺序与开发、生产环境不同,测试使用的IDP并非最后一个注册的方案,因此无法匹配全局默认Cookie;而开发、生产环境测试的IDP刚好是最后注册的方案,默认Cookie匹配成功,因此运行正常。
修复方案
  1. 修正认证方案注册逻辑
    全局仅调用一次services.AddAuthentication()配置基础选项,禁止在循环内反复覆盖全局默认配置,参考修改代码:
// 移到循环外,全局仅调用一次
var authBuilder = services.AddAuthentication();
foreach (var Saml in samlProviderslist)
{
    try
    {
        // 移除循环内的AddAuthentication调用,直接用authBuilder注册方案
        authBuilder
        .AddSaml2(Saml.SchemeName, options =>
        {
            // 原有Saml2配置保持不变
            options.SPOptions = new Sustainsys.Saml2.Configuration.SPOptions()
            {
                AuthenticateRequestSigningBehavior = Sustainsys.Saml2.Configuration.SigningBehavior.Never,
                EntityId = new Sustainsys.Saml2.Metadata.EntityId(Saml.EntityId),
                ReturnUrl = new Uri(Saml.ReturnUrl),
                ModulePath = string.Format("/{0}", Saml.SchemeName)
            };
            // 证书加载、IDP添加等原有逻辑保持不变
            options.Notifications.AcsCommandResultCreated = AcsCommandResultCreated;
            options.IdentityProviders.Add(
                new Sustainsys.Saml2.IdentityProvider(
                new Sustainsys.Saml2.Metadata.EntityId(Saml.IdpEntityId), options.SPOptions)
                {
                    MetadataLocation = Saml.IdpMetadata,
                    AllowUnsolicitedAuthnResponse = true,
                    LoadMetadata = true
                });
        })
        .AddCookie(Saml.SchemeName + "Cookies");
        logger.LogInfo($"Auth Scheme Added : {Saml.SchemeName}");
    }
    catch (Exception ex)
    {
        logger.LogError($"{ErrorCodes.GetErroCode("1002")} { Saml.SchemeName } .Exception :{ex.Message} ");
    }
}
  1. 调整跳转逻辑传递当前Scheme参数
    在AcsCommandResultCreated方法解析出当前Scheme后,将其作为参数追加到跳转URL中:
commandResult.Location = new Uri(jwtRedirectUri + tenantID.Rows[0][0] + $"&protocol=SAML&requestId={requestID}&scheme={schemeName}", UriKind.Relative);
  1. 修改GetTokenResponse逻辑显式认证
    不再依赖全局默认的User.Claims,通过传递的Scheme参数手动完成对应方案的身份认证,获取Claims:
// 新增scheme入参
public async Task<IActionResult> GetTokenResponse(string clientId, string requestId, string scheme, string protocol = "SAML")
{
    _logger.LogInfo("Inside GetTokenResponse.");
    var attributeMappingList = await GetTokenAttributes(clientId, protocol);
    List<Claim> claimAttributes = new List<Claim>();
    var failureRedirectUrl = await _dbConfigSettingRepo.Get(new { SettingName = $"SSO:SAML:FailureRedirectUrl", TenantId = clientId });
    try
    {
        _logger.LogInfo("Inside GetTokenResponse inside try.");
        // 新增:显式调用对应Scheme的认证逻辑
        var authResult = await HttpContext.AuthenticateAsync(scheme + "Cookies");
        if (!authResult.Succeeded)
        {
            _logger.LogError(requestId, clientId, protocol, ErrorCodes.GetErroCode("1007"));
            return Redirect(failureRedirectUrl.SettingValue + "?errorcode=1007");
        }
        // 用authResult.Principal.Claims替代User.Claims
        var userClaims = authResult.Principal.Claims;
        _logger.LogInfo($"Request Id: { requestId}. Claims in SAML response are:\n" + String.Join(",\n", userClaims.Select(o => o.Type + " : " + o.Value)));
        
        // 后续所有使用User.Claims的位置全部替换为userClaims即可,原有业务逻辑保持不变
        if (!attributeMappingList.Any())
        {
            _logger.LogError(requestId, clientId, protocol, ErrorCodes.GetErroCode("1004"));
            return Redirect(failureRedirectUrl.SettingValue + "?errorcode=1004");
        }
        // 剩余原有逻辑保持不变
    }
    catch (Exception ex)
    {
        _logger.LogError(requestId, clientId, protocol, ErrorCodes.GetErroCode("1007"), ex);
        return Redirect(failureRedirectUrl.SettingValue + "?errorcode=1007");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:57:01