Azure AD B2C本地帐户密码在几个小时后停止工作

时间:2017-10-05 15:33:38

标签: azure-ad-b2c

我已根据Active Directory B2C custom policy starter pack for social and local accounts中的示例为社交帐户和本地帐户创建了自定义政策。我已经启用了与Microsoft和Google的登录,并测试了两者都有效,我还启用了使用本地帐户登录。

我看到的问题是本地帐户。我可以创建一个,密码可以正常工作几个小时(不确定多长时间),然后开始提供通用的“无效的用户名或密码”。错误。当我为同一个用户键入错误的密码时,我收到另一条消息“您的密码不正确”(这对应于相关的日志条目)。

我启用了应用程序洞察,只能找到以下例外情况。

如何清除这两个错误的任何帮助都会很棒。

""Statebag"": { ""Complex-CLMS"": {}, ""ValidationRequest"": { ""ContentType"": ""Unspecified"", ""Created"": ""2017-10-04T19:17:49.2510644Z"", ""Key"": ""ValidationRequest"", ""Persistent"": true, ""Value"": ""client_id=307&resource=cf87&username=user%domain.com&password=fakep@ss!123&grant_type=password&scope=openid&nca=1;1;login-NonInteractive;False"" }, ""ValidationResponse"": { ""ContentType"": ""Json"", ""Created"": ""2017-10-04T19:17:49.2510644Z"", ""Key"": ""ValidationResponse"", ""Persistent"": true, ""Value"": ""{\""error\"":\""invalid_grant\"",\""error_description\"":\""AADSTS65001: The user or administrator has not consented to use the application with ID '307' named 'IdentityExperienceFramework'. Send an interactive authorization request for this user and resource.\\r\\nTrace ID: 7c4\\r\\nCorrelation ID: 3cc\\r\\nTimestamp: 2017-10-04 19:17:49Z\"",\""error_codes\"":[65001],\""timestamp\"":\""2017-10-04 19:17:49Z\"",\""trace_id\"":\""7c4\"",\""correlation_id\"":\""3cc\""};1;login-NonInteractive;False"" }, ""ComplexItems"": ""_MachineEventQ, REPRM, TCTX, M_EXCP"" } 这是第二个例外

""Key"": ""Exception"", ""Value"": { ""Kind"": ""Handled"", ""HResult"": ""80131500"", ""Message"": ""The technical Profile with id \""AAD-UserWriteUsingLogonEmail\"" in Policy id \""B2C_1A_signup_signin of Tenant id \""xxx.onmicrosoft.com\"" requires that an error be raised if a claims principal record already exists for storing claims. A claims principal of type \""User\"" with identifier claim type id \""signInNames.emailAddress\"" does already exist."", ""Data"": { ""IsPolicySpecificError"": true, ""TenantId"": ""xxx.onmicrosoft.com"", ""PolicyId"": ""B2C_1A_signup_signin"", ""TechnicalProfile.Id"": ""AAD-UserWriteUsingLogonEmail"", ""ClaimsPrincipal.IdentifierClaim.ClaimTypeId"": ""signInNames.emailAddress"", ""ClaimsPrincipal.PrincipalType"": ""User"", ""CreateClaimsPrincipalIfItDoesNotExist"": ""True"", ""RaiseErrorIfClaimsPrincipalAlreadyExists"": ""True"", ""RaiseErrorIfClaimsPrincipalDoesNotExist"": ""False"" } }

以下是TrustFrameworkExtensions.xml文件的内容。它和示例之间的唯一区别是我使用2个提供程序而不是1。

<?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="xxx.onmicrosoft.com" 
  PolicyId="B2C_1A_TrustFrameworkExtensions" 
  PublicPolicyUri="http://xxx.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions">

  <BasePolicy>
    <TenantId>xxx.onmicrosoft.com</TenantId>
    <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
  </BasePolicy>
  <BuildingBlocks>

  </BuildingBlocks>

  <ClaimsProviders>

    <ClaimsProvider>
      <DisplayName>Local Account SignIn</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="login-NonInteractive">
          <Metadata>
            <Item Key="client_id">307</Item>
            <Item Key="IdTokenAudience">cf8</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="307" />
            <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="cf8" />
          </InputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
        <Domain>Employee SignIn with Azure AD</Domain>
        <DisplayName>Employee Login</DisplayName>
        <TechnicalProfiles>
            <TechnicalProfile Id="AzureADProfile">
                <DisplayName>Employee Login</DisplayName>
                <Description>Login with your GP account</Description>
                <Protocol Name="OpenIdConnect"/>
                <OutputTokenFormat>JWT</OutputTokenFormat>
                <Metadata>
                    <Item Key="METADATA">https://login.windows.net/yyy.onmicrosoft.com/.well-known/openid-configuration</Item>
                    <Item Key="ProviderName">https://sts.windows.net/7de/</Item>
                    <Item Key="client_id">f19</Item>
                    <Item Key="IdTokenAudience">f19</Item>
                    <Item Key="response_types">id_token</Item>
                    <Item Key="UsePolicyInRedirectUri">false</Item>
                </Metadata>
                <CryptographicKeys>
                    <Key Id="client_secret" StorageReferenceId="B2C_1A_AzureADAppSecret"/>
                </CryptographicKeys>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="socialIdpUserId" 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="authenticationSource" DefaultValue="contosoAuthentication" />
                    <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="AzureADContoso" />
                </OutputClaims>
                <OutputClaimsTransformations>
                    <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
                    <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
                    <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
                    <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
                </OutputClaimsTransformations>
                <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop"/>
            </TechnicalProfile>
        </TechnicalProfiles>
    </ClaimsProvider>

    <ClaimsProvider>
      <Domain>google.com</Domain>
      <DisplayName>Google</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Google-OAUTH">
            <DisplayName>Employee Login</DisplayName>
            <Protocol Name="OAuth2" />
            <Metadata>
            <Item Key="ProviderName">google</Item>
            <Item Key="authorization_endpoint">https://accounts.google.com/o/oauth2/auth</Item>
            <Item Key="AccessTokenEndpoint">https://accounts.google.com/o/oauth2/token</Item>
            <Item Key="ClaimsEndpoint">https://www.googleapis.com/oauth2/v1/userinfo</Item>
            <Item Key="scope">email</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">0</Item>
            <Item Key="client_id">zzz.apps.googleusercontent.com</Item>
            </Metadata>
            <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_GoogleSecret" />
            </CryptographicKeys>
            <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="socialIdpUserId" PartnerClaimType="id" />
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
            <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
            <OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="family_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="google.com" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
            </OutputClaims>
            <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
            </OutputClaimsTransformations>
            <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
            <ErrorHandlers>
            <ErrorHandler>
                <ErrorResponseFormat>json</ErrorResponseFormat>
                <ResponseMatch>$[?(@@.error == 'invalid_grant')]</ResponseMatch>
                <Action>Reauthenticate</Action>
                <!--In case of authorization code used error, we don't want the user to select his account again.-->
                <!--AdditionalRequestParameters Key="prompt">select_account</AdditionalRequestParameters-->
            </ErrorHandler>
            </ErrorHandlers>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

  </ClaimsProviders>



  <UserJourneys>
      <UserJourney Id="SignUpOrSignInUsingAzureAD">
      <OrchestrationSteps>

        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>            
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="GoogleExchange" />
            <ClaimsProviderSelection TargetClaimsExchangeId="AzureADExchange" />
          </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="GoogleExchange" TechnicalProfileReferenceId="Google-OAUTH" />
            <ClaimsExchange Id="AzureADExchange" TechnicalProfileReferenceId="AzureADProfile" />
            <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>

        <!-- 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="4" 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="5" 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="6" 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="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

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

</TrustFrameworkPolicy>

2 个答案:

答案 0 :(得分:1)

由于实际错误可能是由于目录中策略和应用程序配置的组合,我将解释为什么需要以这种方式设置这些应用程序,以及可能存在的问题。我希望即使我对根本原因的猜测是错误的,这个解释也可以让你进一步调试这个问题。

考虑一个需要验证用户密码的应用程序。由于应用程序无法访问密码,因此其中一种方法是使用用户的ID和密码向login.microsoftonline.com发送身份验证请求,并查看是否已成功发出令牌。

但是,当此应用程序发送请求时,它必须指定一些资源,并且还必须具有代表用户访问该资源的权限。一种常见的解决方法是管理员代表所有用户授予权限(即同意)。

IEF使用相同的模型。您的策略有两个应用程序,一个作为客户端,代表用户为资源获取令牌。如果您按照&#34; Custom Policies Get Started Page&#34;上的说明操作,则ProxyIdentityExperienceFramework是客户端,IdentityExperienceFramework是资源。根据这些说明,只有ProxyIdentityExperienceFramework可以代表用户获取IdentityExperienceFramework的令牌,反之亦然。

根据日志中的错误消息,似乎您可能已经颠倒了客户端和资源的ID:

  

用户或管理员未同意使用该应用程序   ID&#39; 307&#39;命名&#39; IdentityExperienceFramework &#39;

也就是说,名为IdentityExperienceFramework的客户端无权获取令牌。

因此,您需要在Azure AD门户中检入哪个应用程序可以访问哪个应用程序并更新客户端ID和资源ID。

第二个例外可能是设计,它只是告诉你目录中创建的用户已经存在。这通常在注册时发生,并且根据您的策略设置,它通常会向用户显示一条错误消息,指出该帐户已存在,而他们应该登录。

答案 1 :(得分:0)

此错误

TextBlock

您是否已按Azure中的AZURE AD刀片中的此应用程序上的“授予权限”按钮

第二个例外

看起来您正在尝试再次编写用户主体,并且在元数据中将RaiseErrorIfUserPrincipalExists设置为rue

这个奇怪的事情并没有真正帮助我理解为什么你的密码在几个小时后无法运行

最好的办法是在此处复制政策,我们可以尝试告诉您为什么尝试写入而不是阅读

相关问题