使用 SAML IDP 时如何在 AD B2C 自定义策略中声明映射

How to Claims mapping in AD B2C custom policy when using SAML IDP

我正在尝试使用自定义策略将 SAML IDP 添加到 AD B2C,完成所有设置,B2C 将我重定向到 IDP 的登录页面。但现在我对声明映射步骤感到困惑。我正在关注以下文章,

Set up sign-up and sign-in with SAML identity provider using Azure Active Directory B2C

This是显示IDP发送的属性。下面添加我的技术简介:

<TechnicalProfiles>
    <TechnicalProfile Id="Contoso-SAML2">
      <DisplayName>Saml Test</DisplayName>
      <Description>Login with your SAML identity provider account</Description>
      <Protocol Name="SAML2"/>
      <Metadata>
        <Item Key="PartnerEntity"> https://samltest.id/saml/idp</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_SAMLSigningCert"/>
      </CryptographicKeys>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="uid" />
        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" />
        <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="sn" />
        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" />
        <OutputClaim ClaimTypeReferenceId="email"  PartnerClaimType="mail"/>
        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="samltest.id" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-idp"/>
    </TechnicalProfile>

完成登录后出现以下错误:

AADB2C: A claim with id 'issuerUserId' was not found, which is required by ClaimsTransformation 'CreateAlternativeSecurityId' with id 'CreateAlternativeSecurityId' in policy 'B2C_1A_signup_signin'

我相信这是因为,我还没有完成声明映射。我该如何解决?

• 根据您遇到的错误,您的 <ClaimsProvider> 缺少 ‘socialIdpUserId’ 声明。这是因为缺少 ClaimTypeReferenceId="socialIdPUserId"<OutputClaim> 条目,或者它映射到您的 SAML IdP 未提供的 PartnerClaimType。因此,根据您在下面引用的文档 link,我建议您在自定义策略中使用以下经过修改的 “技术简介” 元素:-

https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-generic-saml?tabs=windows&pivots=b2c-custom-policy#map-the-claims

<TechnicalProfiles>
<TechnicalProfile Id="Contoso-SAML2">
  <DisplayName>Saml Test</DisplayName>
  <Description>Login with your SAML identity provider account</Description>
  <Protocol Name="SAML2"/>
  <Metadata>
    <Item Key="PartnerEntity"> https://samltest.id/saml/idp</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_SAMLSigningCert"/>
  </CryptographicKeys>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="userId"/>
    <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" />
    <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="sn" />
    <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" />
    <OutputClaim ClaimTypeReferenceId="email"  PartnerClaimType="mail"/>
    <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="samltest.id" />
    <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
  </OutputClaims>
  <OutputClaimsTransformations>
    <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
    <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
    <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
    <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
  </OutputClaimsTransformations>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-idp"/>
</TechnicalProfile>

自定义策略技术配置文件中的上述更改应该可以帮助您解决错误。

问题在 Jas Suri - MSFT's 评论的帮助下得到解决。以下是我的 SAML 回复,

<saml:Assertion xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_134d0c388282ca18031a7d00efffa0fc" Version="2.0" IssueInstant="2022-04-29T08:34:35.635Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:Issuer>https://samltest.id/saml/idp</saml:Issuer>
  <saml:Subject>
    <saml:NameID NameQualifier="https://samltest.id/saml/idp" SPNameQualifier="https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">V3QCBLSO2CHF47EMELCG23VN73FLI6ZY</saml:NameID>
    <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
      <saml:SubjectConfirmationData NotOnOrAfter="2022-04-29T08:39:35.646Z" Recipient="https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase/samlp/sso/assertionconsumer" InResponseTo="_c6e2e6b1-518f-4837-9e3e-8e7a0fd6d857" Address="157.46.147.227" />
    </saml:SubjectConfirmation>
  </saml:Subject>
  <saml:Conditions NotBefore="2022-04-29T08:34:35.635Z" NotOnOrAfter="2022-04-29T08:39:35.635Z">
    <saml:AudienceRestriction>
      <saml:Audience>https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AuthnStatement SessionIndex="_ac852acc6d8309dfb667e66ddf371620" AuthnInstant="2022-04-29T08:33:50.718Z">
    <saml:SubjectLocality Address="157.46.147.227" />
    <saml:AuthnContext>
      <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
    </saml:AuthnContext>
  </saml:AuthnStatement>
  <saml:AttributeStatement>
    <saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="eduPersonEntitlement">
      <saml:AttributeValue>urn:mace:dir:entitlement:common-lib-terms</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="uid">
      <saml:AttributeValue>rick</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oasis:names:tc:SAML:attribute:subject-id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
      <saml:AttributeValue xsi:type="xsd:string">rsanchez@samltest.id</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:2.5.4.20" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="telephoneNumber">
      <saml:AttributeValue>+1-555-555-5515</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="https://samltest.id/attributes/role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="role">
      <saml:AttributeValue xsi:type="xsd:string">manager@Samltest.id</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="mail">
      <saml:AttributeValue>rsanchez@samltest.id</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="sn">
      <saml:AttributeValue>Sanchez</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="displayName">
      <saml:AttributeValue>Rick Sanchez</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="givenName">
      <saml:AttributeValue>Rick</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

我在我的自定义策略技术配置文件中使用 PartnerClaimtype 的友好名称而不是名称。我按如下方式更改了技术配置文件,并且效果很好。

    <TechnicalProfile Id="Contoso-SAML2">
      <DisplayName>Saml Test</DisplayName>
      <Description>Login with your SAML identity provider account</Description>
      <Protocol Name="SAML2"/>
      <Metadata>
        <Item Key="PartnerEntity"> https://samltest.id/saml/idp</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_SAMLSigningCert"/>
      </CryptographicKeys>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="urn:oid:0.9.2342.19200300.100.1.1" />
        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="urn:oid:2.5.4.42" />
        <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="urn:oid:2.5.4.4" />
        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="urn:oid:2.16.840.1.113730.3.1.241" />
        <OutputClaim ClaimTypeReferenceId="email"  PartnerClaimType="urn:oid:0.9.2342.19200300.100.1.3"/>
        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="samltest.id" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-idp"/>
    </TechnicalProfile>

谢谢 Jas Suri。