Condividi tramite


Configurare un flusso di credenziali password del proprietario della risorsa in Azure Active Directory B2C

Prima di iniziare, usare il selettore Scegli un tipo di criterio per scegliere il tipo di criterio che si sta configurando. Azure Active Directory B2C offre due metodi per definire il modo in cui gli utenti interagiscono con le applicazioni: tramite flussi utente predefiniti o tramite criteri personalizzati completamente configurabili. I passaggi necessari in questo articolo sono diversi per ogni metodo.

In Azure Active Directory B2C (Azure AD B2C), il flusso delle credenziali password del proprietario della risorsa (ROPC) è un flusso di autenticazione standard OAuth. In questo flusso, un'applicazione, nota anche come relying party, scambia credenziali valide con token. Le credenziali includono un ID utente e una password. I token restituiti sono un token ID, un token di accesso e un token di aggiornamento.

Avviso

È consigliabile non usare il flusso ROPC. Per la maggior parte degli scenari sono disponibili e consigliate alternative più sicure. Questo flusso richiede un livello di attendibilità molto elevato nell'applicazione e comporta rischi che non sono presenti in altri flussi. È consigliabile usare questo flusso solo quando altri flussi più sicuri non sono validi.

Note sul flusso ROPC

In Azure Active Directory B2C (Azure AD B2C) sono supportate le opzioni seguenti:

  • Client nativo: l'interazione dell'utente durante l'autenticazione avviene quando il codice viene eseguito in un dispositivo lato utente. Il dispositivo può essere un'applicazione per dispositivi mobili in esecuzione in un sistema operativo nativo, ad esempio Android e iOS.
  • Flusso client pubblico: nella chiamata API vengono inviate solo le credenziali utente, raccolte da un'applicazione. Le credenziali dell'applicazione non vengono inviate.
  • Aggiunta di nuove attestazioni: il contenuto del token ID può essere modificato per aggiungere nuove attestazioni.

I flussi seguenti non sono supportati:

  • Da server a server: il sistema di protezione delle identità richiede un indirizzo IP affidabile raccolto dal chiamante (il client nativo) come parte dell'interazione. In una chiamata API lato server viene usato solo l'indirizzo IP del server. Se viene superata una soglia dinamica di autenticazioni non riuscite, il sistema di protezione delle identità può identificare un indirizzo IP ripetuto come un utente malintenzionato.
  • Flusso client riservato: l'ID client dell'applicazione viene convalidato, ma il segreto dell'applicazione non viene convalidato.

Quando si usa il flusso ROPC, tenere presente quanto segue:

Registrare un'applicazione

Per registrare un'applicazione nel tenant di Azure AD B2C, è possibile usare la nuova esperienza unificata Registrazioni app oppure l'esperienza legacy Applicazioni (legacy). Altre informazioni sulla nuova esperienza.

  1. Accedi al portale di Azure.
  2. Assicurarsi di usare la directory che contiene il tenant di Azure AD B2C:
    1. Selezionare l'icona Directory e sottoscrizioni nella barra degli strumenti del portale.
    2. Nelle impostazioni del portale | Pagina Directory e sottoscrizioni , trovare la directory di Azure AD B2C nell'elenco Nome directory e quindi selezionare Cambia.
  3. Nella portale di Azure cercare e selezionare Azure AD B2C
  4. Selezionare Registrazioni app e quindi Nuova registrazione.
  5. Immettere un nome per l'applicazione. Ad esempio, ROPC_Auth_app.
  6. Lasciare gli altri valori così come sono e quindi selezionare Registra.
  7. Prendere nota del valore di ID applicazione (client), che sarà necessario in un passaggio successivo.
  8. In Gestisci selezionare Autenticazione.
  9. Selezionare Prova la nuova esperienza (se visualizzato).
  10. In Impostazioni avanzate e sezione Abilitare i flussi per dispositivi mobili e desktop seguenti, selezionare per considerare l'applicazione come client pubblico. Questa impostazione è obbligatoria per il flusso ROPC.
  11. Seleziona Salva.
  12. Nel menu a sinistra, selezionare Manifesto per aprire l'editor del manifesto.
  13. Impostare l'attributo oauth2AllowImplicitFlow su true:
    "oauth2AllowImplicitFlow": true,
    
  14. Seleziona Salva.

Creare un flusso utente per il proprietario della risorsa

  1. Accedere al portale di Azure come amministratore globale del tenant di Azure AD B2C.
  2. Se si ha accesso a più tenant, selezionare l'icona Impostazioni nel menu in alto per passare al tenant di Azure AD B2C dal menu Directory e sottoscrizioni.
  3. Nel portale di Azure cercare e selezionare Azure AD B2C.
  4. Selezionare Flussi utente e selezionare Nuovo flusso utente.
  5. Selezionare Accedi usando le credenziali della password del proprietario della risorsa (ROPC).
  6. In Versione verificare che l'opzione Anteprima sia selezionata e quindi selezionare Crea.
  7. Specificare un nome per il flusso utente, ad esempio ROPC_Auth.
  8. In Attestazioni applicazione selezionare Mostra altro.
  9. Selezionare le attestazioni necessarie per l'applicazione, ad esempio Nome visualizzato, Indirizzo di posta elettronica e Provider di identità.
  10. Seleziona OK e quindi Crea.

Prerequisito

In caso contrario, vedere Introduzione ai criteri personalizzati in Active Directory B2C.

Creare un criterio per il proprietario della risorsa

  1. Aprire il file TrustFrameworkExtensions.xml.

  2. Se non esiste già, aggiungere un elemento ClaimsSchema e i relativi elementi figlio come primo elemento sotto l'elemento BuildingBlocks:

    <ClaimsSchema>
      <ClaimType Id="logonIdentifier">
        <DisplayName>User name or email address that the user can use to sign in</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="resource">
        <DisplayName>The resource parameter passes to the ROPC endpoint</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokenIssuedOnDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokensValidFromDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
    
  3. Dopo ClaimsSchema, aggiungere un elemento ClaimsTransformations e i relativi elementi figlio all'elemento BuildingBlocks:

    <ClaimsTransformations>
      <ClaimsTransformation Id="CreateSubjectClaimFromObjectID" TransformationMethod="CreateStringClaim">
        <InputParameters>
          <InputParameter Id="value" DataType="string" Value="Not supported currently. Use oid claim." />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="sub" TransformationClaimType="createdClaim" />
        </OutputClaims>
      </ClaimsTransformation>
    
      <ClaimsTransformation Id="AssertRefreshTokenIssuedLaterThanValidFromDate" TransformationMethod="AssertDateTimeIsGreaterThan">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" TransformationClaimType="leftOperand" />
          <InputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" TransformationClaimType="rightOperand" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="AssertIfEqualTo" DataType="boolean" Value="false" />
          <InputParameter Id="AssertIfRightOperandIsNotPresent" DataType="boolean" Value="true" />
        </InputParameters>
      </ClaimsTransformation>
    </ClaimsTransformations>
    
  4. Individuare l'elemento ClaimsProvider con un DisplayName di Local Account SignIn e aggiungere il profilo tecnico seguente:

    <TechnicalProfile Id="ResourceOwnerPasswordCredentials-OAUTH2">
      <DisplayName>Local Account SignIn</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <Metadata>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
        <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
        <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>
        <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
        <Item Key="ValidTokenIssuerPrefixes">https://sts.windows.net/</Item>
        <Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item>
        <Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item>
        <Item Key="response_types">id_token</Item>
        <Item Key="response_mode">query</Item>
        <Item Key="scope">email openid</Item>
        <Item Key="grant_type">password</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="logonIdentifier" PartnerClaimType="username" Required="true" DefaultValue="{OIDC:Username}"/>
        <InputClaim ClaimTypeReferenceId="password" Required="true" DefaultValue="{OIDC:Password}" />
        <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
        <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
        <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" />
        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    

    Sostituire il valore DefaultValue di client_id con l'ID applicazione dell'applicazione ProxyIdentityExperienceFramework creato nell'esercitazione preliminare. Sostituire quindi il valore DefaultValue di client_id con l'ID applicazione dell'applicazione IdentityExperienceFramework, anche questo creato nell'esercitazione preliminare.

  5. Aggiungere gli elementi ClaimsProvider seguenti con i relativi profili tecnici all'elemento ClaimsProviders:

    <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AAD-UserReadUsingObjectId-CheckRefreshTokenDate">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertRefreshTokenIssuedLaterThanValidFromDate" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
          </OutputClaimsTransformations>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Session Management</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="SM-RefreshTokenReadAndSetup">
          <DisplayName>Trustframework Policy Engine Refresh Token Setup Technical Profile</DisplayName>
          <Protocol Name="None" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" />
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Token Issuer</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="JwtIssuer">
          <Metadata>
            <!-- Point to the redeem refresh token user journey-->
            <Item Key="RefreshTokenUserJourneyId">ResourceOwnerPasswordCredentials-RedeemRefreshToken</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
  6. Aggiungere un elemento UserJourneys e i relativi elementi figlio all'elemento TrustFrameworkPolicy:

    <UserJourney Id="ResourceOwnerPasswordCredentials">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ResourceOwnerFlow" TechnicalProfileReferenceId="ResourceOwnerPasswordCredentials-OAUTH2" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    <UserJourney Id="ResourceOwnerPasswordCredentials-RedeemRefreshToken">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RefreshTokenSetupExchange" TechnicalProfileReferenceId="SM-RefreshTokenReadAndSetup" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="CheckRefreshTokenDateFromAadExchange" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId-CheckRefreshTokenDate" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    
  7. Nella pagina Criteri personalizzati del tenant di Azure AD B2C selezionare Carica il criterio.

  8. Abilitare Sovrascrivi il criterio se esistente e quindi cercare e selezionare il file TrustFrameworkExtensions.xml.

  9. Selezionare Carica.

Creare un file relying party

È ora necessario aggiornare il file della relying party che avvierà il percorso utente appena creato:

  1. Creare una copia del file SignUpOrSignin.xml nella directory di lavoro, quindi rinominare la copia ROPC_Auth.xml.

  2. Aprire il nuovo file e aggiornare il valore dell'attributo PolicyId per TrustFrameworkPolicy con un valore univoco. L'ID criteri è il nome dei criteri. Ad esempio, B2C_1A_ROPC_Auth.

  3. Modificare il valore dell'attributo ReferenceId in DefaultUserJourney con ResourceOwnerPasswordCredentials.

  4. Modificare l'elemento OutputClaims affinché contenga soltanto le attestazioni seguenti:

    <OutputClaim ClaimTypeReferenceId="sub" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="displayName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="givenName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="surname" DefaultValue="" />
    
  5. Nella pagina Criteri personalizzati del tenant di Azure AD B2C selezionare Carica il criterio.

  6. Abilitare Sovrascrivi il criterio se esistente e quindi cercare e selezionare il file ROPC_Auth.xml.

  7. Selezionare Carica.

Testare il flusso ROPC

Usare l'applicazione di sviluppo API preferita per generare una chiamata API ed esaminare la risposta per eseguire il debug del criterio. Costruire una chiamata come nell'esempio con le informazioni seguenti come corpo della richiesta POST:

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • Sostituire <tenant-name> con il nome del tenant di Azure AD B2C.
  • Sostituire B2C_1A_ROPC_Auth con il nome completo dei criteri delle credenziali password del proprietario della risorsa.
Chiave Valore
username user-account
password password1
grant_type password
ambito openid application-id offline_access
client_id application-id
response_type token id_token
  • Sostituire user-account con il nome di un account utente nel tenant.
  • Sostituire password1 con la password dell'account utente.
  • Sostituire application-id con l'ID applicazione della registrazione di ROPC_Auth_app.
  • Offline_access è facoltativo se si vuole ricevere un token di aggiornamento.

La richiesta POST effettiva è simile all'esempio seguente:

POST /<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.com
Content-Type: application/x-www-form-urlencoded

username=contosouser.outlook.com.ws&password=Passxword1&grant_type=password&scope=openid+bef22d56-552f-4a5b-b90a-1988a7d634ce+offline_access&client_id=bef22d56-552f-4a5b-b90a-1988a7d634ce&response_type=token+id_token

Una risposta con esito positivo con l'accesso offline è simile all'esempio seguente:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki...",
    "token_type": "Bearer",
    "expires_in": "3600",
    "refresh_token": "eyJraWQiOiJacW9pQlp2TW5pYVc2MUY0TnlfR3REVk1EVFBLbUJLb0FUcWQ1ZWFja1hBIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6Ij...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki..."
}

Riscattare un token di aggiornamento

Costruire una chiamata POST come l'esempio seguente. Usare le informazioni riportate nella tabella seguente come corpo della richiesta:

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • Sostituire <tenant-name> con il nome del tenant di Azure AD B2C.
  • Sostituire B2C_1A_ROPC_Auth con il nome completo dei criteri delle credenziali password del proprietario della risorsa.
Chiave Valore
grant_type token di aggiornamento
response_type id_token
client_id application-id
resource application-id
token di aggiornamento refresh-token
  • Sostituire application-id con l'ID applicazione della registrazione di ROPC_Auth_app.
  • Sostituire refresh-token con il refresh_token che è stato inviato nella risposta precedente.

Una risposta con esito positivo è simile all'esempio seguente:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhT...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQn...",
    "token_type": "Bearer",
    "not_before": 1533672990,
    "expires_in": 3600,
    "expires_on": 1533676590,
    "resource": "bef2222d56-552f-4a5b-b90a-1988a7d634c3",
    "id_token_expires_in": 3600,
    "profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiI1MTZmYzA2NS1mZjM2LTRiOTMtYWE1YS1kNmVlZGE3Y2JhYzgiLCJzdWIiOm51bGwsIm5hbWUiOiJEYXZpZE11IiwicHJlZmVycmVkX3VzZXJuYW1lIjpudWxsLCJpZHAiOiJMb2NhbEFjY291bnQifQ",
    "refresh_token": "eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAi...",
    "refresh_token_expires_in": 1209600
}

Risoluzione dei problemi

L'applicazione fornita non è configurata per consentire il flusso implicito "OAuth"

  • Sintomo : si esegue il flusso ROPC e viene visualizzato il messaggio seguente: AADB2C90057: L'applicazione fornita non è configurata per consentire il flusso implicito "OAuth".
  • Possibili cause : il flusso implicito non è consentito per l'applicazione.
  • Soluzione: quando si crea la registrazione dell'app in Azure AD B2C, è necessario modificare manualmente il manifesto dell'applicazione e impostare il valore della oauth2AllowImplicitFlow proprietà su true. Dopo aver configurato la oauth2AllowImplicitFlow proprietà, possono essere necessari alcuni minuti (in genere non più di cinque) affinché la modifica venga modificata.

Usare un SDK nativo o AppAuth

Azure AD B2C soddisfa gli standard OAuth 2.0 per le credenziali password del proprietario della risorsa client pubblico e dovrebbe essere compatibile con la maggior parte degli SDK client. Per informazioni aggiornate, vedere le informazioni relative all'SDK di app native per OAuth 2.0 e OpenID Connect con implementazione delle procedure consigliate moderne.

Passaggi successivi

Scaricare esempi funzionanti, configurati per l'uso con Azure AD B2C da GitHub, per Android e per iOS.