繁体   English   中英

如何使用 Azure AD B2C 自定义策略和 MSAL 在访问令牌中包含自定义声明?

[英]How to include custom claim in access token with Azure AD B2C custom policy and MSAL?

我有 Azure B2C 配置了自定义策略以允许注册和登录本地帐户和多租户 Azure AD。 UI 是 Angular,使用带有.NET Core Web API 后端的 MSAL。 自定义策略定义了一个名为clientIds的自定义声明,该声明通过对内部开发的 Azure Function 的 REST 调用进行填充。

当用户登录时,此自定义声明已成功包含在id_token中。但是,它未包含在发送到 API 的access_token中。如何将其包含在访问令牌中?

其他详情:

  • 我发现有一篇帖子说解决方案是将其作为PersistedClaim添加到SM-AAD技术配置文件中,但没有效果。

  • 如果我在用户流和 API 连接器中配置自定义声明,则一切正常 - 它包含在两个令牌中。 我研究了用户流程的 XML 以寻找线索,但没有得到任何结果。 我不能使用用户流,因为我必须支持多租户 Azure AD。

  • 我已将声明包含在SignUpOrSignin.xml中:

<RelyingParty>
  <DefaultUserJourney ReferenceId="AegisSignUpOrSignIn" />
  <Endpoints>
    <Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" />
  </Endpoints>
  <TechnicalProfile Id="PolicyProfile">
    <DisplayName>PolicyProfile</DisplayName>
    <Protocol Name="OpenIdConnect" />
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="displayName" />
      <OutputClaim ClaimTypeReferenceId="email" />
      <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
      <OutputClaim ClaimTypeReferenceId="identityProvider" />
      <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
      <OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="emails" />
      <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
      <OutputClaim ClaimTypeReferenceId="clientIds" />
    </OutputClaims>
    <SubjectNamingInfo ClaimType="sub" />
  </TechnicalProfile>
</RelyingParty>
  • 我认为解决方案是在TrustFrameworkExtensions.xml中编辑一些内容,但几天来我一直在尝试各种各样的事情但没有成功。 这里是:
<?xml version="1.0" encoding="utf-8" ?>
<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="aegispremierdev.onmicrosoft.com" 
  PolicyId="B2C_1A_TrustFrameworkExtensions" 
  PublicPolicyUri="http://aegispremierdev.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">
  
  <BasePolicy>
    <TenantId>aegispremierdev.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkLocalization</PolicyId>
  </BasePolicy>
  <BuildingBlocks>
    <ClaimsSchema>
      <ClaimType Id="prompt">
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="isForgotPassword">
        <DisplayName>isForgotPassword</DisplayName>
        <DataType>boolean</DataType>
        <AdminHelpText>Whether the user has selected Forgot your Password</AdminHelpText>
      </ClaimType>
      <ClaimType Id="clientIds">
        <DisplayName>Comma-separated list of authorized CRM clients</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
  </BuildingBlocks>

  <ClaimsProviders>

    <ClaimsProvider>
      <Domain>commonaad</Domain>
      <DisplayName>Sign in with Microsoft</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AADCommon-OpenIdConnect">
          <DisplayName>Sign in with Microsoft</DisplayName>
          <Description>Login with your company account</Description>
          <Protocol Name="OpenIdConnect"/>
          <Metadata>
            <Item Key="METADATA">https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration</Item>
            <Item Key="client_id">64e56953-cb54-48ee-ae81-3bd1325050d6</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid profile email</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
            <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
            <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_AzureAdAppSecret"/>
          </CryptographicKeys>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="prompt" PartnerClaimType="prompt" DefaultValue= "select_account"/>
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="azureAdIdpAuthentication" AlwaysUseDefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
            <OutputClaim ClaimTypeReferenceId="othermails" />
            <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email"/>
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
            <!-- <OutputClaim ClaimTypeReferenceId="clientIds" /> Adding it here doesn't help -->
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <DisplayName>Local Account SignIn</DisplayName>
      <TechnicalProfiles>
         <TechnicalProfile Id="login-NonInteractive">
          <Metadata>
            <Item Key="client_id">6a178567-c2fb-4f88-93e8-ed5775869485</Item>
            <Item Key="IdTokenAudience">3290010d-2d76-4fc0-95fc-6c6ad6c637bb</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="6a178567-c2fb-4f88-93e8-ed5775869485" />
            <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="3290010d-2d76-4fc0-95fc-6c6ad6c637bb" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" AlwaysUseDefaultValue="true" />
            <!-- <OutputClaim ClaimTypeReferenceId="clientIds" /> Adding it here doesn't help -->
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <DisplayName>Local Account</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="REST-OnAegisAzureB2CSignUp" />
          </ValidationTechnicalProfiles>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

<!-- Adding it as a PersistedClaim as suggested in the referenced SO post doesn't help -->
<!--    <ClaimsProvider>
      <DisplayName>Session Management</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="SM-AAD">
          <DisplayName>Session Mananagement Provider</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.DefaultSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <PersistedClaims>
            <PersistedClaim ClaimTypeReferenceId="objectId" />
            <PersistedClaim ClaimTypeReferenceId="signInName" />
            <PersistedClaim ClaimTypeReferenceId="authenticationSource" />
            <PersistedClaim ClaimTypeReferenceId="identityProvider" />
            <PersistedClaim ClaimTypeReferenceId="newUser" />
            <PersistedClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" />
            <PersistedClaim ClaimTypeReferenceId="clientIds" />
          </PersistedClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectIdFromSession" DefaultValue="true" />
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>-->
    
    <ClaimsProvider>
      <DisplayName>Self Asserted</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="SelfAsserted-Social">
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="authenticationSource" />
          </InputClaims>
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="REST-OnAegisAzureB2CSignUp"/>
          </ValidationTechnicalProfiles>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <DisplayName>REST APIs - OnAegisAzureB2CSignUp</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="REST-OnAegisAzureB2CSignUp">
          <DisplayName>Verify user exists in DonorOne Users table</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <!-- Set the ServiceUrl with your own REST API endpoint -->
            <Item Key="ServiceUrl">https://apt-fa-azure-b2c-dev-wus2.azurewebsites.net/api/onAegisAzureB2CSignUp</Item>
            <Item Key="SendClaimsIn">Body</Item>
            <Item Key="AuthenticationType">Basic</Item>
            <Item Key="AllowInsecureAuthInProduction">false</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_RestApiUsername" />
            <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_RestApiPassword" />
          </CryptographicKeys>
          <InputClaims>
            <!-- Claims sent to your REST API -->
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="authenticationSource" />
          </InputClaims>
          <OutputClaims>
            <!-- Claims parsed from your REST API -->
            <OutputClaim ClaimTypeReferenceId="clientIds" />
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <DisplayName>REST APIs - OnAegisAzureB2CSignIn</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="REST-OnAegisAzureB2CSignIn">
          <DisplayName>Get user extended profile Azure Function web hook</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://apt-fa-azure-b2c-dev-wus2.azurewebsites.net/api/onAegisAzureB2CSignIn</Item>
            <Item Key="SendClaimsIn">Body</Item>
            <Item Key="AuthenticationType">Basic</Item>
            <Item Key="AllowInsecureAuthInProduction">false</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_RestApiUsername" />
            <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_RestApiPassword" />
          </CryptographicKeys>
          <InputClaims>
            <!-- Claims sent to your REST API -->
            <InputClaim ClaimTypeReferenceId="email" />
            <InputClaim ClaimTypeReferenceId="signInName" />
            <InputClaim ClaimTypeReferenceId="authenticationSource" />
          </InputClaims>
          <OutputClaims>
            <!-- Claims parsed from your REST API -->
            <OutputClaim ClaimTypeReferenceId="clientIds" />
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <DisplayName>Local Account</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="ForgotPassword">
          <DisplayName>Forgot your password?</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="isForgotPassword" DefaultValue="true" AlwaysUseDefaultValue="true"/>
          </OutputClaims>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>
        <TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
          <Metadata>
            <Item Key="setting.forgotPasswordLinkOverride">ForgotPasswordExchange</Item>
          </Metadata>
        </TechnicalProfile>
        <TechnicalProfile Id="LocalAccountWritePasswordUsingObjectId">
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

  </ClaimsProviders>

  <UserJourneys>

    <UserJourney Id="AegisSignUpOrSignIn">
      <OrchestrationSteps>

        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="AzureADCommonExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
          </ClaimsProviderSelections>
          <ClaimsExchanges>
            <ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email" />
          </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="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
            <ClaimsExchange Id="AzureADCommonExchange" TechnicalProfileReferenceId="AADCommon-OpenIdConnect" />
            <ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
          </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>

        <!-- For social IDP authentication, attempt to find the user account in the directory. -->
        <OrchestrationStep Order="4" 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>

        <!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId). 
          This can only happen when authentication happened using a social IDP. If local account was created or authentication done
          using ESTS in step 2, then an user account must exist in the directory by this time. -->
        <OrchestrationStep Order="5" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>objectId</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>
          </Preconditions>
          <ClaimsExchanges>
            <ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" />
          </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="6" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
              <Value>authenticationSource</Value>
              <Value>azureAdIdpAuthentication</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="7" 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="8" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RESTOnAegisAzureB2CSignIn" TechnicalProfileReferenceId="REST-OnAegisAzureB2CSignIn" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <OrchestrationStep Order="9" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
    
    </UserJourneys>

  <SubJourneys>
    <SubJourney Id="PasswordReset" Type="Call">
      <OrchestrationSteps>
        <!-- Validate user's email address. -->
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
          </ClaimsExchanges>
        </OrchestrationStep>

        <!-- Collect and persist a new password. -->
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
      </OrchestrationSteps>
    </SubJourney>
  </SubJourneys>

</TrustFrameworkPolicy>

@JasSuri-MSFT 这就是诀窍 - 谢谢! 这是我添加到 TrustFrameworkExtensions.xml 的TrustFrameworkExtensions.xml

<UserJourney Id="AegisRedeemRefreshToken">
  <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
  <OrchestrationSteps>
    <OrchestrationStep Order="1" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="RefreshTokenSetupExchange" TechnicalProfileReferenceId="RefreshTokenReadAndSetup" />
      </ClaimsExchanges>
    </OrchestrationStep>
    
    <OrchestrationStep Order="2" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CheckRefreshTokenDateFromAadExchange" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId-CheckRefreshTokenDate" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <!-- I inserted step 3, which calls the REST API to return the clientIds claim -->
    <OrchestrationStep Order="3" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="RESTOnAegisAzureB2CSignIn" TechnicalProfileReferenceId="REST-OnAegisAzureB2CSignIn" />
      </ClaimsExchanges>
    </OrchestrationStep>
    
    <OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
</UserJourney>

然后我从SignUpOrSignin.xml引用了这段旅程:

<Endpoint Id="Token" UserJourneyReferenceId="AegisRedeemRefreshToken" />

我的 REST API 希望发送两个声明:emailAddress 和 authenticationSource。 在进行上述更改后它们未包含在内,因此我试图通过覆盖几个技术配置文件来包含它们。 也就是说,我将其添加到 TrustFrameworkExtensions.xml 的TrustFrameworkExtensions.xml部分:

<ClaimsProvider>
  <DisplayName>Refresh token journey</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="RefreshTokenReadAndSetup">
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
      </OutputClaims>
    </TechnicalProfile>
    <TechnicalProfile Id="AAD-UserReadUsingObjectId-CheckRefreshTokenDate">
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" />
      </OutputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

这包括 email 地址,但由于我还不明白 authenticationSource 仍然没有传入的原因。但是对于这个问题,这是 scope 之外的,所以我将在这里结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM