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

配置B2C自定义策略以MS Entra为SAML Idp实现SSO时无法获取断言信息

解决B2C通过SAML集成MS Entra应用无法获取断言信息的问题

问题场景

我有一个关联MS Entra的应用App1,已配置为企业应用启用SAML SSO,仅授权3个用户访问。现在需要在B2C租户中通过这个Entra应用实现SSO,并获取登录用户的邮箱地址。已将Entra中的证书复制到B2C的SamlAssertionSigning元数据,SamlMessageSigning使用新证书,但目前无法获取Entra返回的SAML断言信息——邮箱未返回,userPrincipalName均由B2C生成,其他Entra相关信息也无法获取。

当前配置代码

TechnicalProfile配置

<TechnicalProfile Id="MsEntraId-SAML2">
    <DisplayName>Salesforce</DisplayName>
    <Description>ENtra SAML</Description>
    <Protocol Name="SAML2" />
    <Metadata>
        <!-- <Item Key="RequestsSigned">false</Item> -->
        <Item Key="ResponsesSigned">false</Item>
        <Item Key="WantsEncryptedAssertions">false</Item>
        <Item Key="WantsSignedAssertions">false</Item>
        <Item Key="PartnerEntity">https://login.microsoftonline.com/<guidhere>/federationmetadata/2007-06/federationmetadata.xml</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_EntraMs"/>

        <Key Id="SamlMessageSigning"
             StorageReferenceId="B2C_1A_MsEntraSAMLCert" />
    </CryptographicKeys>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="UserPrincipalName"/>
        <OutputClaim ClaimTypeReferenceId="userPrincipalName"/>
        <OutputClaim ClaimTypeReferenceId="Email" Required="true" PartnerClaimType="Email"/>
        <OutputClaim ClaimTypeReferenceId="objectid" PartnerClaimType="Subject"/>
        <OutputClaim ClaimTypeReferenceId="issuerUserId"
                     PartnerClaimType="userprincipalname" DefaultValue="not found"/>
        <OutputClaim ClaimTypeReferenceId="givenName"
                     PartnerClaimType="user.givenname" />
        <OutputClaim ClaimTypeReferenceId="surname"
                     PartnerClaimType="family_name" />
        <OutputClaim ClaimTypeReferenceId="email"
                     PartnerClaimType="user.mail" />

        <OutputClaim ClaimTypeReferenceId="displayName"
                     PartnerClaimType="username" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource"
                     DefaultValue="socialIdpAuthentication" />
        <OutputClaim ClaimTypeReferenceId="identityProvider"
                     DefaultValue="entra.com" />
    </OutputClaims>
    <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
    </OutputClaimsTransformations>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-idp" />
</TechnicalProfile>

依赖方配置

<RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignInMsEntra" />
    <UserJourneyBehaviors>
        <ScriptExecution>Allow</ScriptExecution>
    </UserJourneyBehaviors>
    <!-- <Endpoints> -->
    <!-- points to refresh token journey when app makes refresh token request -->
    <!-- <Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" /> -->
    <!-- </Endpoints> -->
    <TechnicalProfile Id="PolicyProfile">
        <DisplayName>PolicyProfile</DisplayName>
        <Protocol Name="OpenIdConnect" />
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="userprincipalname" PartnerClaimType="UserPrincipalName"/>
            <OutputClaim ClaimTypeReferenceId="Email"/>
            <OutputClaim ClaimTypeReferenceId="objectid"/>
            <OutputClaim ClaimTypeReferenceId="issuerUserId"/>
            <OutputClaim ClaimTypeReferenceId="displayName"/>
            <OutputClaim ClaimTypeReferenceId="userPrincipalName"/>
            <OutputClaim ClaimTypeReferenceId="userPrincipalName"/>
            <OutputClaim ClaimTypeReferenceId="givenName" />
            <OutputClaim ClaimTypeReferenceId="surname" />
            <OutputClaim ClaimTypeReferenceId="email"
                         PartnerClaimType="user.mail" />
            <OutputClaim ClaimTypeReferenceId="objectId"
                         PartnerClaimType="sub" />
            <OutputClaim ClaimTypeReferenceId="tenantId"
                         AlwaysUseDefaultValue="true"
                         DefaultValue="{Policy:TenantObjectId}" />
            <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
        </OutputClaims>
        <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
</RelyingParty>

问题分析

  1. 声明映射不匹配:Entra返回的SAML断言属性使用标准URI格式(如UPN对应http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn),当前配置用的Email、userprincipalname等非标准命名无法匹配到真实值。
  2. 签名验证配置错误:Entra企业应用默认会签名SAML响应和断言,当前ResponsesSigned="false"、WantsSignedAssertions="false"会导致B2C跳过验证,无法正确解析断言内容。
  3. 冗余声明与转换干扰:重复声明userPrincipalName、objectId会覆盖真实值;CreateRandomUPNUserName和CreateUserPrincipalName会生成B2C本地UPN,直接覆盖Entra返回的UPN。
  4. 缺少响应签名验证密钥:B2C需要配置对应密钥来验证Entra的响应签名,否则会忽略断言内容。

修改后的配置

调整TechnicalProfile配置

<TechnicalProfile Id="MsEntraId-SAML2">
    <DisplayName>MS Entra ID SAML</DisplayName>
    <Description>通过SAML验证MS Entra用户</Description>
    <Protocol Name="SAML2" />
    <Metadata>
        <Item Key="RequestsSigned">false</Item>
        <Item Key="ResponsesSigned">true</Item> <!-- 匹配Entra默认签名设置 -->
        <Item Key="WantsEncryptedAssertions">false</Item>
        <Item Key="WantsSignedAssertions">true</Item> <!-- 要求Entra签名断言 -->
        <Item Key="PartnerEntity">https://login.microsoftonline.com/<guidhere>/federationmetadata/2007-06/federationmetadata.xml</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_EntraMs"/>
        <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_MsEntraSAMLCert" />
        <Key Id="SamlResponseSignatureValidation" StorageReferenceId="B2C_1A_EntraMs"/> <!-- 新增:验证Entra响应签名 -->
    </CryptographicKeys>
    <OutputClaims>
        <!-- 使用Entra标准断言URI映射 -->
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"/>
        <OutputClaim ClaimTypeReferenceId="Email" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" Required="true"/>
        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" />
        <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" />
        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="http://schemas.microsoft.com/identity/claims/displayname" />
        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="entra.com" />
    </OutputClaims>
    <OutputClaimsTransformations>
        <!-- 移除生成本地UPN的转换,保留必要的身份标识转换 -->
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
    </OutputClaimsTransformations>
    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-idp" />
</TechnicalProfile>

调整依赖方配置

<RelyingParty>
    <DefaultUserJourney ReferenceId="SignUpOrSignInMsEntra" />
    <UserJourneyBehaviors>
        <ScriptExecution>Allow</ScriptExecution>
    </UserJourneyBehaviors>
    <TechnicalProfile Id="PolicyProfile">
        <DisplayName>PolicyProfile</DisplayName>
        <Protocol Name="OpenIdConnect" />
        <OutputClaims>
            <!-- 精简声明,避免重复覆盖 -->
            <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn"/>
            <OutputClaim ClaimTypeReferenceId="Email" PartnerClaimType="email"/>
            <OutputClaim ClaimTypeReferenceId="givenName" />
            <OutputClaim ClaimTypeReferenceId="surname" />
            <OutputClaim ClaimTypeReferenceId="displayName" />
            <OutputClaim ClaimTypeReferenceId="issuerUserId" />
            <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
            <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
        </OutputClaims>
        <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
</RelyingParty>

额外检查项

  1. 确认Entra应用的声明配置:
    • 登录Entra门户,进入App1的「SAML配置」→「用户属性与声明」
    • 添加或确认存在以下声明:
      • 名称:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress,源属性选择user.mail
      • 名称:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn,源属性选择user.userprincipalname
  2. 验证证书有效性:确保B2C中存储的Entra证书未过期,且用途包含签名验证
  3. 捕获SAML响应排查:用浏览器SAML tracer插件捕获登录过程中的SAML响应,检查断言内是否包含所需属性,确认映射关系正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:14:54