首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >B2C中的用户名发现

B2C中的用户名发现
EN

Stack Overflow用户
提问于 2022-08-30 07:04:58
回答 2查看 44关注 0票数 0

我正在尝试使用https://github.com/azure-ad-b2c/samples/tree/master/policies/username-discovery配置忘记的用户名流,用户可以在其中提供电子邮件,它将发现用户名,并在策略中调用REST技术配置文件发送电子邮件,但仍然会出现以下错误:

声明交换步骤'2‘中指定的'REST-RestoreUsername’返回的HTTP错误响应,代码'BadRequest‘和原因’坏请求‘.

不知道是什么导致了这个问题。

API { "toEmails": [ "string" ], "templateName": "string", "emailParam": [ "string" ] }所需的JSON有效载荷

不确定是否正确定义了声明转换

代码语言:javascript
运行
复制
<ClaimsTransformation Id="GenerateRequestBody" TransformationMethod="GenerateJson">
    <InputClaims>
      <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="toEmails" />
      <InputClaim ClaimTypeReferenceId="forgotuserid" TransformationClaimType="templateName" />
      <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="emailParam" />
      <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="emailParam" />
      <InputClaim ClaimTypeReferenceId="signInNames.userName" TransformationClaimType="emailParam" />
    </InputClaims>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="forgotuserid" TransformationClaimType="outputClaim" />
    </OutputClaims>
  </ClaimsTransformation>

TP:

代码语言:javascript
运行
复制
 <!-- this technical profile collects the user's email address, call
        validation technical profile to discover the user name and send the 
        email with the username to the end user -->
    <TechnicalProfile Id="SelfAsserted-UsernameDiscovery">
      <DisplayName>Forgot your username?</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>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
        <OutputClaim ClaimTypeReferenceId="displayName" />
        <OutputClaim ClaimTypeReferenceId="surname" />
        <OutputClaim ClaimTypeReferenceId="signInNames.userName" />
      </OutputClaims>
      <ValidationTechnicalProfiles>
        <ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingEmailAddress-NoError" />
        <ValidationTechnicalProfile ReferenceId="REST-RestoreUsername" ContinueOnError="true">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
              <Value>signInNames.userName</Value>
              <Action>SkipThisValidationTechnicalProfile</Action>
            </Precondition>
          </Preconditions>
        </ValidationTechnicalProfile>
      </ValidationTechnicalProfiles>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>

    <TechnicalProfile Id="SelfAsserted-UserMessage">
      <DisplayName>UserNameDiscoveryMessage</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>
        <!-- hide the continue and cancel buttons -->
        <Item Key="setting.showContinueButton">false</Item>
        <Item Key="setting.showCancelButton">false</Item>
      </Metadata>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GetUserMessage" />
      </InputClaimsTransformations>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="userMessage" />
      </InputClaims>
      <OutputClaims>
        <!-- Show the paragraph claim with the message to the user -->
        <OutputClaim ClaimTypeReferenceId="userMessage" />
      </OutputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>

REST:

代码语言:javascript
运行
复制
<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <!-- Custom Restful service that sends emails -->
    <TechnicalProfile Id="REST-RestoreUsername">
      <DisplayName>Validate user input data and return loyaltyNumber claim</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <!--Action required: value of the ServiceUrl according to your application location-->
        <Item Key="ServiceUrl">http://XXXXXXXXXXX/api/v1/Email/SendEmail</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">None</Item>
        <Item Key="allowInsecureAuthInProduction">true</Item>
        <Item Key="DebugMode">true</Item>
        <!--<Item Key="DefaultUserMessageIfRequestFailed">Cannot process your request right now, please try again later.</Item>-->
      </Metadata>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateRequestBody" />
      </InputClaimsTransformations>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="forgotuserid" />
      </InputClaims>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

编制步骤:

代码语言:javascript
运行
复制
<UserJourneys>
<UserJourney Id="SignUpOrSignInMFAOption" DefaultCpimIssuerTechnicalProfileReferenceId="JwtIssuer">
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
      <ClaimsProviderSelections>
        <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninUsernameExchange" />
        <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
        <ClaimsProviderSelection TargetClaimsExchangeId="SelfAssertedUsernameDiscoveryExchange" />
      </ClaimsProviderSelections>
      <ClaimsExchanges>
        <ClaimsExchange Id="LocalAccountSigninUsernameExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Username" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Check if the user has selected to sign in using one of the social providers -->
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>objectId</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SignUpWithLogonUsernameExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonName" />
        <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
        <ClaimsExchange Id="SelfAssertedUsernameDiscoveryExchange" TechnicalProfileReferenceId="SelfAsserted-UsernameDiscovery" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="3" Type="InvokeSubJourney">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
          <Value>isForgotPassword</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <JourneyList>
        <Candidate SubJourneyReferenceId="PasswordReset" />
      </JourneyList>
    </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>

    <OrchestrationStep Order="5" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>extension_mfaByPhoneOrEmail</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="SelfAsserted-Select-MFA-Method" TechnicalProfileReferenceId="SelfAsserted-Select-MFA-Method" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Throw error if control was bypassed -->
    <OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Return-MFA-Method-Incorrect-Error">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>extension_mfaByPhoneOrEmail</Value>
          <Value>email</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>extension_mfaByPhoneOrEmail</Value>
          <Value>phone</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
    </OrchestrationStep>

    <!-- Phone verification: If MFA is not required, the next three steps (#5-#7) should be removed.
         This step checks whether there's a phone number on record,  for the user. If found, then the user is challenged to verify it. -->
    <OrchestrationStep Order="7" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
          <Value>isActiveMFASession</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
        <!-- If the preferred MFA method is not 'phone' skip this orchestration step-->
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>extension_mfaByPhoneOrEmail</Value>
          <Value>phone</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="PhoneFactor-Verify" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- Save MFA phone number: The precondition verifies whether the user provided a new number in the 
         previous step. If so, then the phone number is stored in the directory for future authentication 
         requests. -->
    <OrchestrationStep Order="8" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
          <Value>newPhoneNumberEntered</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="AADUserWriteWithObjectId" TechnicalProfileReferenceId="AAD-UserWritePhoneNumberUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- MFA with email-->
    <OrchestrationStep Order="9" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>extension_mfaByPhoneOrEmail</Value>
          <Value>email</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="Email-Verify" TechnicalProfileReferenceId="EmailVerifyOnSignIn" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- check if change password is required. If yes, ask the user to reset the password-->
    <OrchestrationStep Order="10" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>authenticationSource</Value>
          <Value>socialIdpAuthentication</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>skipPasswordReset</Value>
          <Value>True</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="11" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
EN

回答 2

Stack Overflow用户

发布于 2022-08-30 08:53:56

您在示例中编译了REST并将其部署到可以公开访问的地方吗?

如果你和邮递员一起测试它会起作用吗?

该示例使用SendGrid。你把SendGrid设置成正确无误了吗

更新

根据有效载荷,它应该如下所示:

代码语言:javascript
运行
复制
<ClaimsTransformation Id="GenerateRequestBody" TransformationMethod="GenerateJson">
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="toEmails.0.email"/>       
        <InputClaim ClaimTypeReferenceId="forgotuserid" TransformationClaimType="templateName"/>
        <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="emailParam.0.givenName"/>
        <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="emailParam.0.surname"/>
        <InputClaim ClaimTypeReferenceId="signInNames.userName" TransformationClaimType="emailParam.0.userName"/>
    </InputClaims>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="request" TransformationClaimType="outputClaim"/>
    </OutputClaims>
</ClaimsTransformation>

最好能看到预期输出的样本。

更新2

代码语言:javascript
运行
复制
<ClaimsTransformation Id="GenerateRequestBody" TransformationMethod="GenerateJson">
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="toEmails.0.email"/>
        <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="emailParam.0.givenName"/>
        <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="emailParam.0.surname"/>
        <InputClaim ClaimTypeReferenceId="signInNames.userName" TransformationClaimType="emailParam.0.userName"/>
    </InputClaims>
    <InputParameters>
        <InputParameter Id="templateName"" DataType="string" Value="forgotuserid"/>         
    </InputParameters>
    <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="request" TransformationClaimType="outputClaim"/>
    </OutputClaims>
</ClaimsTransformation>
票数 1
EN

Stack Overflow用户

发布于 2022-09-05 08:06:04

@rbrayb -谢谢你的帮助,非常感谢。已经在CT下面使用了。

代码语言:javascript
运行
复制
 <ClaimsTransformation Id="CreateJSONBody" TransformationMethod="GenerateJson">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="toEmails.0" />
    <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="emailParam.0" />
    <InputClaim ClaimTypeReferenceId="surName" TransformationClaimType="emailParam.1" />
    <InputClaim ClaimTypeReferenceId="signInNames.userName" TransformationClaimType="emailParam.2"/>
  </InputClaims>
  <InputParameters>
    <InputParameter Id="templateName" DataType="string" Value="forgotuserid" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="RequestPayload" TransformationClaimType="outputClaim" />
  </OutputClaims>
</ClaimsTransformation>

这解决了这个问题。

再次感谢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73538422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档