为什么我的 AD B2C 自定义策略在添加调用 Azure 函数的编排步骤后返回 invalid_grant?

问题描述 投票:0回答:1

我有一个与授权代码流程配合使用的登录策略和用户旅程。但是,当我添加接受查询字符串值并将其发送到 Azure 函数的编排步骤时,/authorize 之后的 /token 调用将返回带有以下正文的 HTTP 400:

{
    "error": "invalid_grant",
    "error_description": "AADB2C90085: The service has encountered an internal error. Please reauthenticate and try again."
}

我用两种方式测试这个:

  1. 使用授权代码流的 msal-browser-3.11.1 的 React SPA。策略更改之间的身份验证配置没有任何变化。
  2. Azure Identity Experience Framework 门户的“立即运行端点”使用不使用授权代码流的虚拟应用程序。回复网址为https://jwt.ms/

预先修改的策略适用于这两者。

只要所选应用程序不使用授权代码流,修改后的策略在使用身份体验框架门户中提供的“立即运行端点”时就可以正常工作。但是,当使用带有授权代码流的 React SPA 时,/token 会损坏。

注意:以下代码示例使用占位符值

原政策:

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
    PolicySchemaVersion="0.3.0.0" 
    TenantId="placeholder.onmicrosoft.com" 
    PolicyId="b2c_1a_signin" 
    PublicPolicyUri="http://placeholder.onmicrosoft.com/b2c_1a_signin" 
    TenantObjectId="my tenant id">
    <BasePolicy>
        <TenantId>placeholder.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignIn" />
        <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="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

原始用户旅程:

<UserJourney Id="SignIn">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <!-- This step reads any user attributes that we may not have received when in the token. -->
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

修改后的政策:

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
    PolicySchemaVersion="0.3.0.0" 
    TenantId="placeholder.onmicrosoft.com" 
    PolicyId="b2c_1a_signin" 
    PublicPolicyUri="http://placeholder.onmicrosoft.com/b2c_1a_signin" 
    TenantObjectId="my tenant id">
    <BasePolicy>
        <TenantId>placeholder.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignIn" />
        <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="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
                <OutputClaim ClaimTypeReferenceId="qsValue" DefaultValue="{OAUTH-KV:qsValue}" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

修改后的用户旅程:

<UserJourney Id="SignIn">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <!-- This step reads any user attributes that we may not have received when in the token. -->
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CallMyAzureFunction" TechnicalProfileReferenceId="AzureFunction"></ClaimsExchange>
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>

调用 Azure 函数的新声明提供程序:

<ClaimsProvider>
  <DisplayName>Claims</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="AzureFunction">
      <DisplayName>Calls an Azure Function to check whether the query string value is valid</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">Azure Function Service URL placeholder</Item>
        <Item Key="AuthenticationType">None</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AllowInsecureAuthInProduction">true</Item>
      </Metadata>
      <InputClaims>
        <InputClaim Required="true" ClaimTypeReferenceId="objectId" />
        <InputClaim ClaimTypeReferenceId="qsValue" DefaultValue="{OAUTH-KV:qsValue}" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="qsValue" />
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

查询字符串参数的声明类型:

<ClaimType Id="qsValue">
  <DisplayName>Query String Value</DisplayName>
  <DataType>string</DataType>
  <UserHelpText>A value passed in the query string</UserHelpText>
</ClaimType>

以下是 Application Insights 中对 React SPA 进行的失败令牌调用的跟踪。这是相关 ID 的唯一应用程序洞察。

[
  {
    "Kind": "Headers",
    "Content": {
      "UserJourneyRecorderEndpoint": "urn:journeyrecorder:applicationinsights",
      "CorrelationId": "3cf51ffc-0093-468e-bda1-cc3022e5883b",
      "EventInstance": "Event:TOKEN",
      "TenantId": "placeholder.onmicrosoft.com",
      "PolicyId": "B2C_1A_signin"
    }
  },
  {
    "Kind": "Transition",
    "Content": {
      "EventName": "TOKEN",
      "StateName": "Initial"
    }
  },
  {
    "Kind": "Predicate",
    "Content": "Web.TPEngine.StateMachineHandlers.IsTokenExchangeValidRequest"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "Statebag": {
        "MACHSTATE": {
          "c": "2024-04-03T16:14:01.8426102Z",
          "k": "MACHSTATE",
          "v": "Initial",
          "p": true
        },
        "JC": {
          "c": "2024-04-03T16:14:01.8416127Z",
          "k": "JC",
          "v": "en",
          "p": true
        },
        "ComplexItems": "_MachineEventQ, TCTX"
      },
      "PredicateResult": "True"
    }
  },
  {
    "Kind": "Predicate",
    "Content": "Web.TPEngine.StateMachineHandlers.IsTokenExchangeOnBehalfOfFlow"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "PredicateResult": "False"
    }
  },
  {
    "Kind": "Predicate",
    "Content": "Web.TPEngine.StateMachineHandlers.IsTokenExchangeCustomClientCredentialsFlow"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "PredicateResult": "False"
    }
  },
  {
    "Kind": "Predicate",
    "Content": "Web.TPEngine.StateMachineHandlers.IsTokenExchangeResourceOwnerFlow"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "PredicateResult": "False"
    }
  },
  {
    "Kind": "Predicate",
    "Content": "Web.TPEngine.StateMachineHandlers.ShouldTokenExchangeRunAsUserJourneyHandler"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "PredicateResult": "False"
    }
  },
  {
    "Kind": "Action",
    "Content": "Web.TPEngine.StateMachineHandlers.TokenExchangeHandler"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": false,
      "Statebag": {
        "Complex-CLMS": {
          "tenantId": "tenant id"
        },
        "CI": {
          "c": "2024-04-03T16:14:01.8546106Z",
          "k": "CI",
          "v": "bf57499d-ca05-4a27-a281-dcd9b32c3e15",
          "p": true
        },
        "CT": {
          "c": "2024-04-03T16:14:01.9176155Z",
          "k": "CT",
          "v": "Spa",
          "p": true
        },
        "ComplexItems": "_MachineEventQ, TCTX, REPRM, AUPRM, PRMCH"
      }
    }
  },
  {
    "Kind": "Action",
    "Content": "Web.TPEngine.StateMachineHandlers.TransactionEndHandler"
  },
  {
    "Kind": "HandlerResult",
    "Content": {
      "Result": true
    }
  }
]

解决方案:

阅读这篇博文后我意识到我的错误:https://blog.wojtek.pro/aad-b2c-quick-tips-query-string-parameters/

问题不在于对 Azure 函数的调用,而在于我传递查询字符串参数值的方式。

我添加了一个声明提供程序,它可以获取查询字符串参数,而不是到处依赖 {OAUTH-KV:qsValue}。然后,我添加了一个声明交换编排步骤,该步骤调用所述声明提供程序,并将其作为我的 SignIn 用户旅程中的第一个编排步骤。 qsValue 参数现在从查询字符串中提取,并在整个过程中持续存在,就像我想要的那样。

这是我的最终配置:

查询字符串参数的声明类型:

<ClaimType Id="qsValue">
  <DisplayName>Query String Value</DisplayName>
  <DataType>string</DataType>
  <UserHelpText>A value passed in the query string</UserHelpText>
</ClaimType>

获取查询字符串参数的新声明提供者:

<ClaimsProvider>
 <DisplayName>Get query string value</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="GetValueFromQueryString">
       <DisplayName>Populate query string value claim with parameter value</DisplayName>
       <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
       <Metadata>
         <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
       </Metadata>
       <OutputClaims>
         <OutputClaim ClaimTypeReferenceId="qsValue" DefaultValue="{OAUTH-KV:qsValue}" AlwaysUseDefaultValue="true"/>
      </OutputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

调用 Azure 函数的声明提供者:

<ClaimsProvider>
  <DisplayName>Claims</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="AzureFunction">
      <DisplayName>Calls an Azure Function to check whether the query string value is valid</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">Azure Function Service URL placeholder</Item>
        <Item Key="AuthenticationType">None</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AllowInsecureAuthInProduction">true</Item>
      </Metadata>
      <InputClaims>
        <InputClaim Required="true" ClaimTypeReferenceId="objectId" />
        <InputClaim ClaimTypeReferenceId="qsValue" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="qsValue" />
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

政策:

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
    PolicySchemaVersion="0.3.0.0" 
    TenantId="placeholder.onmicrosoft.com" 
    PolicyId="b2c_1a_signin" 
    PublicPolicyUri="http://placeholder.onmicrosoft.com/b2c_1a_signin" 
    TenantObjectId="my tenant id">
    <BasePolicy>
        <TenantId>placeholder.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignIn" />
        <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="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
                <OutputClaim ClaimTypeReferenceId="qsValue" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

用户旅程:

<UserJourney Id="SignIn">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="GetQueryStringValue" TechnicalProfileReferenceId="GetValueFromQueryString" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="2" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <!-- This step reads any user attributes that we may not have received when in the token. -->
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CallMyAzureFunction" TechnicalProfileReferenceId="AzureFunction"></ClaimsExchange>
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
azure-functions azure-ad-b2c openid-connect azure-ad-b2c-custom-policy pkce
1个回答
0
投票

阅读这篇博文后我意识到我的错误:https://blog.wojtek.pro/aad-b2c-quick-tips-query-string-parameters/

问题不在于对 Azure 函数的调用,而在于我传递查询字符串参数值的方式。

我添加了一个声明提供程序,它可以获取查询字符串参数,而不是到处依赖 {OAUTH-KV:qsValue}。然后,我添加了一个声明交换编排步骤,该步骤调用所述声明提供程序,并将其作为我的 SignIn 用户旅程中的第一个编排步骤。 qsValue 参数现在从查询字符串中提取,并按照我想要的方式在整个过程中持续存在。

这是我的最终配置:

查询字符串参数的声明类型:

<ClaimType Id="qsValue">
  <DisplayName>Query String Value</DisplayName>
  <DataType>string</DataType>
  <UserHelpText>A value passed in the query string</UserHelpText>
</ClaimType>

获取查询字符串参数的新声明提供者:

<ClaimsProvider>
 <DisplayName>Get query string value</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="GetValueFromQueryString">
       <DisplayName>Populate query string value claim with parameter value</DisplayName>
       <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
       <Metadata>
         <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
       </Metadata>
       <OutputClaims>
         <OutputClaim ClaimTypeReferenceId="qsValue" DefaultValue="{OAUTH-KV:qsValue}" AlwaysUseDefaultValue="true"/>
      </OutputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

调用 Azure 函数的声明提供者:

<ClaimsProvider>
  <DisplayName>Claims</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="AzureFunction">
      <DisplayName>Calls an Azure Function to check whether the query string value is valid</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">Azure Function Service URL placeholder</Item>
        <Item Key="AuthenticationType">None</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AllowInsecureAuthInProduction">true</Item>
      </Metadata>
      <InputClaims>
        <InputClaim Required="true" ClaimTypeReferenceId="objectId" />
        <InputClaim ClaimTypeReferenceId="qsValue" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="qsValue" />
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

政策:

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
    PolicySchemaVersion="0.3.0.0" 
    TenantId="placeholder.onmicrosoft.com" 
    PolicyId="b2c_1a_signin" 
    PublicPolicyUri="http://placeholder.onmicrosoft.com/b2c_1a_signin" 
    TenantObjectId="my tenant id">
    <BasePolicy>
        <TenantId>placeholder.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
    </BasePolicy>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignIn" />
        <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="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
                <OutputClaim ClaimTypeReferenceId="qsValue" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

用户旅程:

<UserJourney Id="SignIn">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="GetQueryStringValue" TechnicalProfileReferenceId="GetValueFromQueryString" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="2" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <!-- This step reads any user attributes that we may not have received when in the token. -->
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="4" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CallMyAzureFunction" TechnicalProfileReferenceId="AzureFunction"></ClaimsExchange>
      </ClaimsExchanges>
    </OrchestrationStep>
    <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
© www.soinside.com 2019 - 2024. All rights reserved.