Azure-AD-B2C令牌格式

时间:2020-11-02 21:00:09

标签: azure-ad-b2c

我们已经构建了一个服务,该服务调用cosmos DB以获得以ID令牌发送的自定义声明。 REST API的输出根据下面的预期令牌格式

{"personalAttributes":{"guid":"1b92e96e28b14737acac11d23dcdd3d0","familyName":"ABC","givenName":"PQR","name":"PQR","preferredUserName":"PQR","upn":"PQR@XYZ.com",
"physicalLocation":"London, UK"
"roles":"Engineer","Engineer","Engineer",
"scopes":{"scopeName":"Application 2 - Pipe Spool install","initiative":"nan","operation":"nan","WBS":"nan"},
{"roleName":"Engineer","jobPosition":"Engineer","rolePermissions":"read, report, archive"},
{"roleName":"Engineer","jobPosition":"Engineer","rolePermissions":"read, report, archive"},
{"roleName":"Engineer","jobPosition":"Engineer","rolePermissions":"read, report, archive"}}

但是,当B2C将其包含在ID令牌中时,它会附加/和。我们尝试格式化输出,这导致B2C甚至没有生成ID令牌。请告知我们如何克服这个问题

TIA

4 个答案:

答案 0 :(得分:1)

看起来您正试图要求 B2C 输出一个复杂对象作为声明值。这不受支持,因此 B2C 将对象转换为字符串 - 导致您看到的转义 JSON 数据。

编辑以提高清晰度:从 CosmosDB 返回的 personalAttributes 值不是您在 ClaimsSchema 中定义的 StringCollection(数组)。它是一个 JSON 对象。 B2C 不支持对象声明类型 - 您需要从对象中提取所需的确切值。

答案 1 :(得分:0)

您需要应用GetClaimFromJson transformation从JSON中提取声明。

答案 2 :(得分:0)

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="xxxx.onmicrosoft.com" PolicyId="B2C_1A_oboTrustFrameworkExtensions" PublicPolicyUri="http://xxxx.onmicrosoft.com/B2C_1A_oboTrustFrameworkExtensions" TenantObjectId="3dc9a24f-ed39-4635-b182-e35aadde9cb2">
  <BasePolicy>
    <TenantId>xxxx.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_oboTrustFrameworkBase</PolicyId>
  </BasePolicy>
  <BuildingBlocks>
    <ClaimsSchema>
      <ClaimType Id="clientId">
        <DisplayName>OIDC client id</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="personalAttributes">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="roles">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="scopes">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="tokenOwner">
        <DisplayName>aud claim in OBO token</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="jsonSourceClaim">
        <DisplayName>JSON output from Custom Service</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="GetClaimsFromJson">
        <DisplayName>JSON output from Custom Service</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
    <ClaimsTransformations>
      <ClaimsTransformation Id="AssertClientIdAndAudAreEqual" TransformationMethod="AssertStringClaimsAreEqual">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="client_id" TransformationClaimType="inputClaim1" />
          <InputClaim ClaimTypeReferenceId="tokenOwner" TransformationClaimType="inputClaim2" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase" />
        </InputParameters>
      </ClaimsTransformation>
      <ClaimsTransformation Id="GetClaimsFromJsonTransformation" TransformationMethod="GetClaimsFromJsonArray">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="jsonSourceClaim" TransformationClaimType="jsonSource" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="errorOnMissingClaims" DataType="boolean" Value="false" />
          <InputParameter Id="includeEmptyClaims" DataType="boolean" Value="false" />
          <InputParameter Id="jsonSourceKeyName" DataType="string" Value="key" />
          <InputParameter Id="jsonSourceValueName" DataType="string" Value="value" />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="personalAttributes" />
          <OutputClaim ClaimTypeReferenceId="roles" />
          <OutputClaim ClaimTypeReferenceId="scopes" />
        </OutputClaims>
      </ClaimsTransformation>
    </ClaimsTransformations>
  </BuildingBlocks>
  <ClaimsProviders>
    <!-- Used for custom extension attribute storage -->
    <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AAD-Common">
          <Metadata>
            <Item Key="ApplicationObjectId">xxxxxx</Item>
            <Item Key="ClientId">xxxxxx</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <Domain>bechtel</Domain>
      <DisplayName>Bechtel AAD</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Bechtel-AAD">
          <DisplayName>Work or school account</DisplayName>
          <Description>Login with your work or school account</Description>
          <Protocol Name="OpenIdConnect" />
          <Metadata>
            <Item Key="METADATA">https://login.microsoftonline.com/xxxx/v2.0/.well-known/openid-configuration</Item>
            <!-- Update the Client ID below to the Application ID -->
            <Item Key="client_id">xxxxxx</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid profile</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
            <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
            <!-- The key below allows you to specify each of the Azure AD tenants that can be used to sign in. Update the GUIDs below for each tenant. -->
            <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/22d635a3-3930-4779-a82d-155e2d13b75e</Item>
            <!-- The commented key below specifies that users from any tenant can sign-in. Uncomment if you would like anyone with an Azure AD account to be able to sign in. -->
            <!--<Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item> -->
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_BECHTELSECRET" />
          </CryptographicKeys>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid" />
            <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
            <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
            <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="preferred_username" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
            <!--OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" /-->
            <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="bechtel" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Facebook</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Facebook-OAUTH">
          <Metadata>
            <Item Key="client_id">facebook_clientid</Item>
            <Item Key="scope">email public_profile</Item>
            <Item Key="ClaimsEndpoint">https://graph.facebook.com/me?fields=id,first_name,last_name,name,email</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Local Account SignIn</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="login-NonInteractive">
          <Metadata>
            <Item Key="client_id">db6c8fe9-368f-48a0-af63-19ad47d91e90</Item>
            <Item Key="IdTokenAudience">5169b8e9-5bcd-4b04-b5f1-d3ca801bbbef</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="db6c8fe9-368f-48a0-af63-19ad47d91e90" />
            <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="5169b8e9-5bcd-4b04-b5f1-d3ca801bbbef" />
          </InputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>REST APIs</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="REST-GetCustomClaim">
          <DisplayName>Get a custom claim</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <!--<Item Key="ServiceUrl">https://beciamobo.azurewebsites.net/CustomClaims</Item> -->
            <Item Key="ServiceUrl">https://xxxxx.azurewebsites.net/xxxxx</Item>
            <Item Key="SendClaimsIn">QueryString</Item>
            <!-- Set AuthenticationType to Basic or ClientCertificate in production environments -->
            <Item Key="AuthenticationType">None</Item>
            <!-- REMOVE the following line in production environments -->
            <Item Key="AllowInsecureAuthInProduction">true</Item>
          </Metadata>
          <InputClaims>
            <!-- Claims sent to your REST API -->
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="scope" DefaultValue="{OIDC:Scope}" AlwaysUseDefaultValue="true" />
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="{OIDC:ClientId}" AlwaysUseDefaultValue="true" />
          </InputClaims>
          <OutputClaims>
            <!-- Claims parsed from your REST API -->
            <OutputClaim ClaimTypeReferenceId="personalAttributes" />
            <OutputClaim ClaimTypeReferenceId="roles" />
            <OutputClaim ClaimTypeReferenceId="scopes" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="GetClaimsFromJsonTransformation" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Self Asserted</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="ValidateOBORequest">
          <DisplayName>User ID signup</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="tokenOwner" />
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="{OIDC:ClientId}" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="tokenOwner" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertClientIdAndAudAreEqual" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>
  <UserJourneys>
    <UserJourney Id="SUSI">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="AADExchange" />
            <!--ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /-->
          </ClaimsProviderSelections>
          <!--ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges-->
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <!--Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions-->
          <ClaimsExchanges>
            <ClaimsExchange Id="AADExchange" TechnicalProfileReferenceId="Bechtel-AAD" />
            <!--ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" /-->
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- For social IDP authentication, attempt to find the user account in the directory. -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <!--Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>localAccountAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions-->
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- This step reads any user attributes that we may not have received when authenticating using ESTS so they can be sent 
          in the token. -->
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>socialIdpAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- The previous step (SelfAsserted-Social) could have been skipped if there were no attributes to collect 
            from the user. So, in that case, create the user in the directory if one does not already exist 
            (verified using objectId which would be set from the last step if account was created in the directory. -->
        <OrchestrationStep Order="5" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="6" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RESTGetCustomClaim" TechnicalProfileReferenceId="REST-GetCustomClaim" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    <UserJourney Id="OBO">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="Validate" TechnicalProfileReferenceId="ValidateOBORequest" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RESTGetCustomClaim" TechnicalProfileReferenceId="REST-GetCustomClaim" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
  </UserJourneys>
</TrustFrameworkPolicy>

答案 3 :(得分:0)

请参阅下面的政策

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="xxxx.onmicrosoft.com" PolicyId="B2C_1A_oboTrustFrameworkExtensions" PublicPolicyUri="http://xxxx.onmicrosoft.com/B2C_1A_oboTrustFrameworkExtensions" TenantObjectId="3dc9a24f-ed39-4635-b182-e35aadde9cb2">
  <BasePolicy>
    <TenantId>xxxx.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_oboTrustFrameworkBase</PolicyId>
  </BasePolicy>
  <BuildingBlocks>
    <ClaimsSchema>
      <ClaimType Id="clientId">
        <DisplayName>OIDC client id</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="personalAttributes">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="roles">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="scopes">
        <DisplayName>Custom claim</DisplayName>
        <DataType>stringCollection</DataType>
      </ClaimType>
      <ClaimType Id="tokenOwner">
        <DisplayName>aud claim in OBO token</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="jsonSourceClaim">
        <DisplayName>JSON output from Custom Service</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="GetClaimsFromJson">
        <DisplayName>JSON output from Custom Service</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
    <ClaimsTransformations>
      <ClaimsTransformation Id="AssertClientIdAndAudAreEqual" TransformationMethod="AssertStringClaimsAreEqual">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="client_id" TransformationClaimType="inputClaim1" />
          <InputClaim ClaimTypeReferenceId="tokenOwner" TransformationClaimType="inputClaim2" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="stringComparison" DataType="string" Value="ordinalIgnoreCase" />
        </InputParameters>
      </ClaimsTransformation>
      <ClaimsTransformation Id="GetClaimsFromJsonTransformation" TransformationMethod="GetClaimsFromJsonArray">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="jsonSourceClaim" TransformationClaimType="jsonSource" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="errorOnMissingClaims" DataType="boolean" Value="false" />
          <InputParameter Id="includeEmptyClaims" DataType="boolean" Value="false" />
          <InputParameter Id="jsonSourceKeyName" DataType="string" Value="key" />
          <InputParameter Id="jsonSourceValueName" DataType="string" Value="value" />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="personalAttributes" />
          <OutputClaim ClaimTypeReferenceId="roles" />
          <OutputClaim ClaimTypeReferenceId="scopes" />
        </OutputClaims>
      </ClaimsTransformation>
    </ClaimsTransformations>
  </BuildingBlocks>
  <ClaimsProviders>
    <!-- Used for custom extension attribute storage -->
    <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AAD-Common">
          <Metadata>
            <Item Key="ApplicationObjectId">xxxxxx</Item>
            <Item Key="ClientId">xxxxxx</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <Domain>bechtel</Domain>
      <DisplayName>Bechtel AAD</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Bechtel-AAD">
          <DisplayName>Work or school account</DisplayName>
          <Description>Login with your work or school account</Description>
          <Protocol Name="OpenIdConnect" />
          <Metadata>
            <Item Key="METADATA">https://login.microsoftonline.com/xxxx/v2.0/.well-known/openid-configuration</Item>
            <!-- Update the Client ID below to the Application ID -->
            <Item Key="client_id">xxxxxx</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid profile</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
            <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
            <!-- The key below allows you to specify each of the Azure AD tenants that can be used to sign in. Update the GUIDs below for each tenant. -->
            <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/22d635a3-3930-4779-a82d-155e2d13b75e</Item>
            <!-- The commented key below specifies that users from any tenant can sign-in. Uncomment if you would like anyone with an Azure AD account to be able to sign in. -->
            <!--<Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item> -->
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_BECHTELSECRET" />
          </CryptographicKeys>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid" />
            <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
            <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
            <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="preferred_username" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
            <!--OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" /-->
            <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="bechtel" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Facebook</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Facebook-OAUTH">
          <Metadata>
            <Item Key="client_id">facebook_clientid</Item>
            <Item Key="scope">email public_profile</Item>
            <Item Key="ClaimsEndpoint">https://graph.facebook.com/me?fields=id,first_name,last_name,name,email</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Local Account SignIn</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="login-NonInteractive">
          <Metadata>
            <Item Key="client_id">db6c8fe9-368f-48a0-af63-19ad47d91e90</Item>
            <Item Key="IdTokenAudience">5169b8e9-5bcd-4b04-b5f1-d3ca801bbbef</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="db6c8fe9-368f-48a0-af63-19ad47d91e90" />
            <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="5169b8e9-5bcd-4b04-b5f1-d3ca801bbbef" />
          </InputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>REST APIs</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="REST-GetCustomClaim">
          <DisplayName>Get a custom claim</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <!--<Item Key="ServiceUrl">https://beciamobo.azurewebsites.net/CustomClaims</Item> -->
            <Item Key="ServiceUrl">https://xxxxx.azurewebsites.net/xxxxx</Item>
            <Item Key="SendClaimsIn">QueryString</Item>
            <!-- Set AuthenticationType to Basic or ClientCertificate in production environments -->
            <Item Key="AuthenticationType">None</Item>
            <!-- REMOVE the following line in production environments -->
            <Item Key="AllowInsecureAuthInProduction">true</Item>
          </Metadata>
          <InputClaims>
            <!-- Claims sent to your REST API -->
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="scope" DefaultValue="{OIDC:Scope}" AlwaysUseDefaultValue="true" />
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="{OIDC:ClientId}" AlwaysUseDefaultValue="true" />
          </InputClaims>
          <OutputClaims>
            <!-- Claims parsed from your REST API -->
            <OutputClaim ClaimTypeReferenceId="personalAttributes" />
            <OutputClaim ClaimTypeReferenceId="roles" />
            <OutputClaim ClaimTypeReferenceId="scopes" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="GetClaimsFromJsonTransformation" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    <ClaimsProvider>
      <DisplayName>Self Asserted</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="ValidateOBORequest">
          <DisplayName>User ID signup</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="tokenOwner" />
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="{OIDC:ClientId}" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="tokenOwner" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertClientIdAndAudAreEqual" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
  </ClaimsProviders>
  <UserJourneys>
    <UserJourney Id="SUSI">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection TargetClaimsExchangeId="AADExchange" />
            <!--ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /-->
          </ClaimsProviderSelections>
          <!--ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </ClaimsExchanges-->
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <!--Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions-->
          <ClaimsExchanges>
            <ClaimsExchange Id="AADExchange" TechnicalProfileReferenceId="Bechtel-AAD" />
            <!--ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" /-->
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- For social IDP authentication, attempt to find the user account in the directory. -->
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <!--Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>localAccountAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions-->
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId" TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- This step reads any user attributes that we may not have received when authenticating using ESTS so they can be sent 
          in the token. -->
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>socialIdpAuthentication</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <!-- The previous step (SelfAsserted-Social) could have been skipped if there were no attributes to collect 
            from the user. So, in that case, create the user in the directory if one does not already exist 
            (verified using objectId which would be set from the last step if account was created in the directory. -->
        <OrchestrationStep Order="5" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserWrite" TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="6" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RESTGetCustomClaim" TechnicalProfileReferenceId="REST-GetCustomClaim" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    <UserJourney Id="OBO">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="Validate" TechnicalProfileReferenceId="ValidateOBORequest" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RESTGetCustomClaim" TechnicalProfileReferenceId="REST-GetCustomClaim" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
  </UserJourneys>
</TrustFrameworkPolicy>