Personalizzare le attestazioni rilasciate nel token Web JSON (JWT) per le applicazioni aziendali

Microsoft Identity Platform supporta l'accesso Single Sign-On (SSO) con la maggior parte delle applicazioni preintegrate nella raccolta di applicazioni e nelle applicazioni personalizzate di Microsoft Entra. Quando un utente esegue l'autenticazione a un'applicazione tramite Microsoft Identity Platform usando il protocollo OIDC, Microsoft Identity Platform invia un token all'applicazione. L'applicazione convalida e usa il token per firmare l'utente anziché richiedere un nome utente e una password.

Questi token JSON Web (JWT) usati dalle applicazioni OIDC e OAuth contengono informazioni sull'utente noto come attestazioni. Un'attestazione è un insieme di informazioni relative ad un utente dichiarate da un provider di identità all'interno del token rilasciato per tale utente. In una risposta OIDC i dati delle attestazioni sono in genere contenuti nel token ID rilasciato dal provider di identità sotto forma di token JWT.

Visualizzare o modificare le attestazioni

Suggerimento

I passaggi descritti in questo articolo possono variare leggermente in base al portale da cui si inizia.

Per visualizzare o modificare le attestazioni rilasciate nel token JWT nell'applicazione:

  1. Accedere all'interfaccia di amministrazione di Microsoft Entra come almeno un'applicazione cloud Amministrazione istrator.
  2. Passare a Applicazioni di identità>Applicazioni>aziendali>Tutte le applicazioni.
  3. Selezionare l'applicazione, selezionare Single Sign-On nel menu a sinistra e quindi selezionare Modifica nella sezione Attributi e attestazioni .

Un'applicazione potrebbe richiedere la personalizzazione delle attestazioni per vari motivi. Ad esempio, quando un'applicazione richiede un set diverso di URI attestazioni o valori attestazioni. Usando la sezione Attributi e attestazioni , è possibile aggiungere o rimuovere un'attestazione per l'applicazione. È anche possibile creare un'attestazione personalizzata specifica per un'applicazione in base al caso d'uso.

I passaggi seguenti descrivono come assegnare un valore costante:

  1. Selezionare l'attestazione da modificare.
  2. Immettere il valore costante senza virgolette nell'attributo Source in base all'organizzazione e quindi selezionare Salva.

La panoramica attributi visualizza il valore costante.

Trasformazioni speciali delle attestazioni

È possibile usare le seguenti funzioni speciali di trasformazione delle attestazioni.

Funzione Descrizione
ExtractMailPrefix() Rimuove il suffisso del dominio dall'indirizzo di posta elettronica o dal nome dell'entità utente. Questa funzione estrae solo la prima parte del nome utente. Ad esempio, joe_smith anziché joe_smith@contoso.com.
ToLower() Converte i caratteri dell'attributo selezionato in minuscole.
ToUpper() Converte i caratteri dell'attributo selezionato in maiuscole.

Aggiungere attestazioni specifiche dell'applicazione

Per aggiungere attestazioni specifiche dell'applicazione:

  1. In Attributi utente e intestazioni selezionare Aggiungi nuova attestazione per aprire la pagina Gestisci attestazioni utente.
  2. Immettere il nome delle attestazioni. Il valore non deve necessariamente seguire un modello URI. Se è necessario un modello di URI, è possibile inserirlo nel campo Spazio dei nomi.
  3. Selezionare l'opzione di Origine da cui l'attestazione recupererà il valore. È possibile selezionare un attributo utente nell'elenco a discesa degli attributi di origine oppure applicare una trasformazione all'attributo utente prima di crearlo come attestazione.

Trasformazioni delle attestazioni

Per applicare una trasformazione a un attributo utente:

  1. In Gestisci l'attestazioneselezionare Trasformazione come origine dell'attestazione per aprire la pagina Gestisci la trasformazione.
  2. Selezionare la funzione nell'elenco a discesa Trasformazione. A seconda della funzione selezionata, specificare i parametri e un valore costante da valutare nella trasformazione.
  3. Considerare l'origine come multivalore indica se la trasformazione viene applicata a tutti i valori o solo alla prima. Per impostazione predefinita, il primo elemento di un'attestazione multivalore viene applicato alle trasformazioni. Quando si seleziona questa casella, garantisce che venga applicata a tutti. Questa casella di controllo è abilitata solo per gli attributi multivalore. Ad esempio: user.proxyaddresses.
  4. Per applicare più trasformazioni, selezionare Aggiungi trasformazione. È possibile applicare un massimo di due trasformazioni a un'attestazione. È ad esempio possibile estrarre prima il prefisso dell'indirizzo di posta elettronica da user.mail. Quindi, impostare la stringa in maiuscolo.

Per trasformare le attestazioni, è possibile usare le funzioni seguenti.

Funzione Descrizione
ExtractMailPrefix() Rimuove il suffisso del dominio dall'indirizzo di posta elettronica o dal nome dell'entità utente. Questa funzione estrae solo la prima parte del nome utente. Ad esempio, joe_smith anziché joe_smith@contoso.com.
Join() Crea un nuovo valore creando un join tra due attributi. Facoltativamente, è possibile usare un separatore tra i due attributi. Per la trasformazione dell'attestazione NameID, la funzione Join() ha un comportamento specifico quando l'input della trasformazione ha una parte di dominio. Rimuove la parte del dominio dall'input prima di unirla al separatore e al parametro selezionato. Ad esempio, se l'input della trasformazione è e il separatore è joe_smith@contoso.com@ e il parametro è fabrikam.com, questa combinazione di input restituisce joe_smith@fabrikam.com.
ToLowercase() Converte i caratteri dell'attributo selezionato in minuscole.
ToUppercase() Converte i caratteri dell'attributo selezionato in maiuscole.
Contains() Restituisce un attributo o una costante se l'input corrisponde al valore specificato. In caso contrario, è possibile specificare un altro output se non esiste alcuna corrispondenza.
Ad esempio, se si vuole generare un'attestazione in cui il valore è l'indirizzo di posta elettronica dell'utente se contiene il dominio @contoso.com, in caso contrario si vuole restituire il nome dell'entità utente. Per eseguire questa funzione, configurare i valori seguenti:
Parametro 1 (input): user.email
Valore: "@contoso.com"
Parametro 2 (output): user.email
Parametro 3 (output se non esistono corrispondenze): user.userprincipalname
EndWith() Restituisce un attributo o una costante se l'input termina con il valore specificato. In caso contrario, è possibile specificare un altro output se non esiste alcuna corrispondenza.
Ad esempio, se si vuole generare un'attestazione in cui il valore è l'ID dipendente dell'utente se l'ID dipendente termina con 000, in caso contrario si vuole restituire un attributo di estensione. Per eseguire questa funzione, configurare i valori seguenti:
Parametro 1 (input): user.employeeid
Valore: "000"
Parametro 2 (output): user.employeeid
Parametro 3 (output se non esistono corrispondenze): user.extensionattribute1
StartWith() Restituisce un attributo o una costante se l'input inizia con il valore specificato. In caso contrario, è possibile specificare un altro output se non esiste alcuna corrispondenza.
Ad esempio, se si vuole generare un'attestazione in cui il valore è l'ID dipendente dell'utente se il paese o l'area geografica inizia con US, in caso contrario si vuole restituire un attributo di estensione. Per eseguire questa funzione, configurare i valori seguenti:
Parametro 1 (input): user.country
Valore: "US"
Parametro 2 (output): user.employeeid
Parametro 3 (output se non esistono corrispondenze): user.extensionattribute1
Extract() - Dopo la corrispondenza Restituisce la sottostringa dopo aver trovato una corrispondenza con il valore specificato.
Ad esempio, se il valore dell'input è Finance_BSimon, il valore corrispondente è Finance_, l'output dell'attestazione è BSimon.
Extract() - Prima della corrispondenza Restituisce la sottostringa finché non trova una corrispondenza con il valore specificato.
Ad esempio, se il valore dell'input è BSimon_US, il valore corrispondente è _US, l'output dell'attestazione è BSimon.
Extract() - Tra corrispondenze Restituisce la sottostringa finché non trova una corrispondenza con il valore specificato.
Ad esempio, se il valore dell'input è Finance_BSimon_US, il primo valore corrispondente è Finance_, il secondo valore corrispondente è _US, l'output dell'attestazione è BSimon.
ExtractAlpha() - Prefisso Restituisce la parte alfabetica del prefisso della stringa.
Ad esempio, se il valore dell'input è BSimon_123, restituisce BSimon.
ExtractAlpha() - Suffisso Restituisce la parte alfabetica del suffisso della stringa.
Ad esempio, se il valore dell'input è 123_Simon, restituisce Simon.
ExtractNumeric() - Prefisso Restituisce la parte numerica del prefisso della stringa.
Ad esempio, se il valore dell'input è 123_BSimon, restituisce 123.
ExtractNumeric() - Suffisso Restituisce la parte numerica del suffisso della stringa.
Ad esempio, se il valore dell'input è BSimon_123, restituisce 123.
IfEmpty() Restituisce un attributo o una costante se l'input è Null o vuoto.
Ad esempio, se si vuole restituire un attributo archiviato in un attributo di estensione se l'ID dipendente per un determinato utente è vuoto. Per eseguire questa funzione, configurare i valori seguenti:
Parametro 1 (input): user.employeeid
Parametro 2 (output): user.extensionattribute1
Parametro 3 (output se non esistono corrispondenze): user.employeeid
IfNotEmpty() Restituisce un attributo o una costante se l'input non è null o vuoto.
Ad esempio, se si vuole restituire un attributo archiviato in un attributo di estensione se l'ID dipendente per un determinato utente non è vuoto. Per eseguire questa funzione, configurare i valori seguenti:
Parametro 1 (input): user.employeeid
Parametro 2 (output): user.extensionattribute1
Substring() - Lunghezza fissa Estrae parti di un tipo di attestazione di stringa, a partire dal carattere in corrispondenza della posizione specificata, e restituisce il numero di caratteri specificato.
SourceClaim: origine attestazione della trasformazione che deve essere eseguita.
StartIndex: posizione del carattere iniziale in base zero di una sottostringa in questa istanza.
Length : lunghezza in caratteri della sottostringa.
Ad esempio:
sourceClaim - PleaseExtractThisNow
StartIndex - 6
Lunghezza - 11
Output: ExtractThis
Substring() - EndOfString Estrae parti di un tipo di attestazione stringa, a partire dal carattere nella posizione specificata e restituisce il resto dell'attestazione dall'indice iniziale specificato.
SourceClaim: origine attestazione della trasformazione.
StartIndex: posizione del carattere iniziale in base zero di una sottostringa in questa istanza.
Ad esempio:
sourceClaim - PleaseExtractThisNow
StartIndex - 6
Output: ExtractThisNow
RegexReplace() La trasformazione RegexReplace() accetta come parametri di input:
- Parametro 1: un attributo utente come input regex
- Opzione per considerare attendibile l'origine come multivalore
- Modello regex
- Modello di sostituzione. Il modello di sostituzione può contenere un formato di testo statico insieme a un riferimento che punta ai gruppi di output regex e a più parametri di input.

Se sono necessarie altre trasformazioni, inviare l'idea nel forum di commenti e suggerimenti in Microsoft Entra ID nella categoria di applicazioni SaaS.

Trasformazione delle attestazioni basate su regex

L'immagine seguente mostra un esempio del primo livello di trasformazione:

Screenshot of the first level of transformation.

Nella tabella seguente vengono fornite informazioni sul primo livello di trasformazioni. Le azioni elencate nella tabella corrispondono alle etichette dell'immagine precedente. Selezionare Modifica per aprire il pannello di trasformazione delle attestazioni.

Azione Campo Descrizione
1 Transformation Selezionare l'opzione RegexReplace() nelle opzioni trasformazione per usare il metodo di trasformazione delle attestazioni basate su regex per la trasformazione delle attestazioni.
2 Parameter 1 Input per la trasformazione dell'espressione regolare. Ad esempio, user.mail con un indirizzo di posta elettronica utente, admin@fabrikam.comad esempio .
3 Treat source as multivalued Alcuni attributi utente di input possono essere attributi utente multivalore. Se l'attributo utente selezionato supporta più valori e l'utente vuole usare più valori per la trasformazione, è necessario selezionare Considera origine come multivalore. Se questa opzione è selezionata, tutti i valori vengono usati per la corrispondenza regex; in caso contrario, viene usato solo il primo valore.
4 Regex pattern Espressione regolare valutata rispetto al valore dell'attributo utente selezionato come Parametro 1. Ad esempio, un'espressione regolare per estrarre l'alias utente dall'indirizzo di posta elettronica dell'utente viene rappresentata come (?'domain'^.*?)(?i)(\@fabrikam\.com)$.
5 Add additional parameter Per la trasformazione è possibile usare più attributi utente. I valori degli attributi verranno quindi uniti con l'output della trasformazione regex. Sono supportati fino a cinque parametri.
6 Replacement pattern Il modello di sostituzione è il modello di testo, che contiene segnaposto per il risultato regex. Tutti i nomi dei gruppi devono essere racchiusi tra parentesi graffe, ad esempio {group-name}. Si supponga che l'amministrazione voglia usare l'alias utente con un altro nome di dominio, ad esempio xyz.com e unire il nome del paese con esso. In questo caso, il modello di sostituzione sarà {country}.{domain}@xyz.com, dove {country} è il valore del parametro di input e {domain} è l'output del gruppo dalla valutazione dell'espressione regolare. In questo caso, il risultato previsto è US.swmal@xyz.com.

L'immagine seguente mostra un esempio del secondo livello di trasformazione:

Screenshot of second level of claims transformation.

Nella tabella seguente vengono fornite informazioni sul secondo livello di trasformazioni. Le azioni elencate nella tabella corrispondono alle etichette dell'immagine precedente.

Azione Campo Descrizione
1 Transformation Le trasformazioni delle attestazioni basate su regex non sono limitate alla prima trasformazione e possono essere usate anche come trasformazione di secondo livello. Qualsiasi altro metodo di trasformazione può essere usato come prima trasformazione.
2 Parameter 1 Se RegexReplace() è selezionato come trasformazione di secondo livello, l'output della trasformazione di primo livello viene usato come input per la trasformazione di secondo livello. Per applicare la trasformazione, l'espressione regex di secondo livello deve corrispondere all'output della prima trasformazione.
3 Regex pattern Il criterio Regex è l'espressione regolare per la trasformazione di secondo livello.
4 Parameter input Input degli attributi utente per le trasformazioni di secondo livello.
5 Parameter input Amministrazione istrators può eliminare il parametro di input selezionato se non è più necessario.
6 Replacement pattern Il modello di sostituzione è il modello di testo, che contiene segnaposto per il nome del gruppo di risultati regex, il nome del gruppo di parametri di input e il valore di testo statico. Tutti i nomi di gruppo devono essere racchiusi tra parentesi graffe, {group-name}ad esempio . Si supponga che l'amministrazione voglia usare l'alias utente con un altro nome di dominio, ad esempio xyz.com e unire il nome del paese con esso. In questo caso, il modello di sostituzione sarà {country}.{domain}@xyz.com, dove {country} è il valore del parametro di input e {domain} è l'output del gruppo dalla valutazione dell'espressione regolare. In questo caso, il risultato previsto è US.swmal@xyz.com.
7 Test transformation La trasformazione RegexReplace() viene valutata solo se il valore dell'attributo utente selezionato per il parametro 1 corrisponde all'espressione regolare fornita nella casella di testo Modello Regex. Se non corrispondono, il valore predefinito dell'attestazione viene aggiunto al token. Per convalidare l'espressione regolare rispetto al valore del parametro di input, è disponibile un'esperienza di test all'interno del pannello trasformazione. Questa esperienza di test opera solo su valori fittizi. Quando vengono usati più parametri di input, il nome del parametro viene aggiunto al risultato del test anziché al valore effettivo. Per accedere alla sezione test, selezionare Trasformazione Test.

L'immagine seguente mostra un esempio di test delle trasformazioni:

Screenshot of testing the transformation.

Nella tabella seguente vengono fornite informazioni sul test delle trasformazioni. Le azioni elencate nella tabella corrispondono alle etichette dell'immagine precedente.

Azione Campo Descrizione
1 Test transformation Selezionare il pulsante Chiudi o (X) per nascondere la sezione test ed eseguire di nuovo il rendering del pulsante Trasformazione Test nel pannello.
2 Test regex input Accetta l'input usato per la valutazione del test dell'espressione regolare. Nel caso in cui la trasformazione delle attestazioni basate su regex sia configurata come trasformazione di secondo livello, fornire un valore che rappresenta l'output previsto della prima trasformazione.
3 Run test Dopo aver specificato l'input regex di test e aver configurato il modello Regex, i parametri Modello di sostituzione e Input, l'espressione può essere valutata selezionando Esegui test.
4 Test transformation result Se la valutazione ha esito positivo, viene eseguito il rendering di un output della trasformazione test sull'etichetta risultato della trasformazione Test.
5 Remove transformation La trasformazione di secondo livello può essere rimossa selezionando Rimuovi trasformazione.
6 Specify output if no match Quando un valore di input regex viene configurato in base al parametro 1 che non corrisponde all'espressione regolare, la trasformazione viene ignorata. In questi casi, è possibile configurare l'attributo utente alternativo, che viene aggiunto al token per l'attestazione selezionando Specifica output se non esiste alcuna corrispondenza.
7 Parameter 3 Se è necessario restituire un attributo utente alternativo quando non esiste alcuna corrispondenza e Specificare l'output se non è selezionata alcuna corrispondenza , è possibile selezionare un attributo utente alternativo usando l'elenco a discesa. Questo elenco a discesa è disponibile nel parametro 3 (output se non corrisponde).
8 Summary Nella parte inferiore del pannello viene visualizzato un riepilogo completo del formato che spiega il significato della trasformazione in testo semplice.
9 Add Dopo aver verificato le impostazioni di configurazione per la trasformazione, è possibile salvarle in un criterio delle attestazioni selezionando Aggiungi. Selezionare Salva nel pannello Gestisci attestazione per salvare le modifiche.

La trasformazione RegexReplace() è disponibile anche per le trasformazioni delle attestazioni di gruppo.

Convalide della trasformazione

Un messaggio fornisce altre informazioni quando si verificano le condizioni seguenti dopo aver selezionato Aggiungi o Esegui test:

  • Sono stati usati parametri di input con attributi utente duplicati.
  • Trovati parametri di input inutilizzati. I parametri di input definiti devono avere il rispettivo utilizzo nel testo modello di sostituzione.
  • L'input regex di test fornito non corrisponde all'espressione regolare fornita.
  • Non vengono trovate origini per i gruppi nel modello di sostituzione.

Generare attestazioni in base alle condizioni

È possibile specificare l'origine di un'attestazione in base al tipo di utente e al gruppo a cui appartiene.

Il tipo di utente può essere:

  • Any : tutti gli utenti possono accedere all'applicazione.
  • Membri: membro nativo del tenant
  • Tutti gli utenti guest: l'utente è stato spostato da un'organizzazione esterna con o senza MICROSOFT Entra ID.
  • Utenti guest Di Microsoft Entra: l'utente guest appartiene a un'altra organizzazione usando l'ID Microsoft Entra.
  • Guest esterni: l'utente guest appartiene a un'organizzazione esterna che non ha l'ID Microsoft Entra.

Uno scenario in cui il tipo di utente è utile è quando l'origine di un'attestazione è diversa per un guest e un dipendente che accede a un'applicazione. È possibile specificare che se l'utente è un dipendente, ottenere nameID da user.email. Se l'utente è un guest, nameID proviene da user.extensionattribute1.

Per aggiungere una condizione per l'attestazione:

  1. In Gestisci l'attestazione espandere Condizioni dell'attestazione.
  2. Selezionare il tipo di utente.
  3. Selezionare il gruppo o i gruppi a cui l'utente deve appartenere. È possibile selezionare fino a 50 gruppi univoci in tutte le attestazioni per una determinata applicazione.
  4. Selezionare l'opzione di Origine da cui l'attestazione recupererà il valore. È possibile selezionare un attributo utente nell'elenco a discesa degli attributi di origine oppure applicare una trasformazione all'attributo utente prima di crearlo come attestazione.

L'ordine in cui si aggiungono le condizioni è importante. Microsoft Entra valuta prima tutte le condizioni con origine Attribute e quindi valuta tutte le condizioni con l'origine Transformation per decidere quale valore emettere nell'attestazione. Microsoft Entra ID valuta le condizioni con la stessa origine dall'alto verso il basso. L'attestazione genera l'ultimo valore che corrisponde all'espressione nell'attestazione. Le trasformazioni, IsNotEmpty ad esempio e Contains agiscono come restrizioni.

Britta Simon, ad esempio, è un utente guest nel tenant di Contoso. Britta appartiene a un'altra organizzazione che usa anche Microsoft Entra ID. Data la configurazione seguente per l'applicazione Fabrikam, quando Britta tenta di accedere a Fabrikam, Microsoft Identity Platform valuta le condizioni.

Prima di tutto, Microsoft Identity Platform verifica se il tipo di utente di Britta è Tutti gli utenti guest. Poiché il tipo è Tutti gli utenti guest, Microsoft Identity Platform assegna l'origine per l'attestazione a user.extensionattribute1. In secondo luogo, Microsoft Identity Platform verifica se il tipo di utente di Britta è guest Di Microsoft Entra. Poiché il tipo è Tutti gli utenti guest, Microsoft Identity Platform assegna l'origine per l'attestazione a user.mail. Infine, l'attestazione viene generata con un valore di user.mail per Britta.

Come altro esempio, considerare quando Britta Simon tenta di accedere usando la configurazione seguente. Microsoft Entra valuta innanzitutto tutte le condizioni con l'origine Attribute. L'origine dell'attestazione è user.mail quando il tipo di utente di Britta è microsoft Entra guest. Successivamente, Microsoft Entra ID valuta le trasformazioni. Poiché Britta è un guest, user.extensionattribute1 è la nuova origine per l'attestazione. Poiché Britta è in microsoft Entra guest, user.othermail è la nuova origine per questa attestazione. Infine, l'attestazione viene generata con un valore di user.othermail per Britta.

Come esempio finale, considerare cosa accade se Britta non user.othermail ha configurato o è vuoto. L'attestazione torna a user.extensionattribute1 ignorare la voce della condizione in entrambi i casi.

Considerazioni sulla sicurezza

Le applicazioni che ricevono token si basano su valori attestazioni che non possono essere manomessi. Quando si modifica il contenuto del token tramite la personalizzazione delle attestazioni, questi presupposti potrebbero non essere più corretti. Le applicazioni devono riconoscere in modo esplicito che i token sono stati modificati per proteggersi dalle personalizzazioni create da utenti malintenzionati. Protezione da personalizzazioni non appropriate in uno dei modi seguenti:

Senza questo, Microsoft Entra ID restituisce un codice di errore AADSTS50146.

Configurare una chiave di firma personalizzata

Per le app multi-tenant, deve essere usata una chiave di firma personalizzata. Non impostare acceptMappedClaims nel manifesto dell'app. quando si configura un'app nella portale di Azure, si ottiene un oggetto di registrazione dell'app e un'entità servizio nel tenant. L'app usa la chiave di accesso globale di Azure, che non può essere usata per personalizzare le attestazioni nei token. Per ottenere attestazioni personalizzate nei token, creare una chiave di accesso personalizzata da un certificato e aggiungerla all'entità servizio. A scopo di test, è possibile usare un certificato autofirmato. Dopo aver configurato la chiave di firma personalizzata, il codice dell'applicazione deve convalidare la chiave di firma del token.

Aggiungere le informazioni seguenti all'entità servizio:

Estrarre la chiave pubblica e privata con codifica Base 64 dall'esportazione di file PFX del certificato. Assicurarsi che per l'oggetto keyIdkeyCredential usato per "Sign" corrisponda a keyId di .passwordCredential È possibile generare customkeyIdentifier recuperando l'hash dell'identificazione personale del certificato.

Richiedi

Nota

Disabilitare prima di tutto la configurazione del blocco dell'entità servizio nelle app appena create dal pannello registrazioni dell'app dell'interfaccia di amministrazione di Microsoft Entra prima di tentare di eseguire una patch nell'entità servizio, con conseguente richiesta non valida 400.

Nell'esempio seguente viene illustrato il formato della richiesta HTTP PATCH per aggiungere una chiave di firma personalizzata a un'entità servizio. Il valore "key" nella keyCredentials proprietà viene abbreviato per la leggibilità. Il valore è codificato in base 64. Per la chiave privata, l'utilizzo della proprietà è Sign. Per la chiave pubblica, l'utilizzo della proprietà è Verify.

PATCH https://graph.microsoft.com/v1.0/servicePrincipals/f47a6776-bca7-4f2e-bc6c-eec59d058e3e

Content-type: servicePrincipals/json
Authorization: Bearer {token}

{
    "keyCredentials":[
        {
            "customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=", 
            "endDateTime": "2021-04-22T22:10:13Z",
            "keyId": "4c266507-3e74-4b91-aeba-18a25b450f6e",
            "startDateTime": "2020-04-22T21:50:13Z",
            "type": "X509CertAndPassword",
            "usage": "Sign",
            "key":"MIIKIAIBAz.....HBgUrDgMCERE20nuTptI9MEFCh2Ih2jaaLZBZGeZBRFVNXeZmAAgIH0A==",
            "displayName": "CN=contoso"
        },
        {
            "customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=",
            "endDateTime": "2021-04-22T22:10:13Z",
            "keyId": "e35a7d11-fef0-49ad-9f3e-aacbe0a42c42",
            "startDateTime": "2020-04-22T21:50:13Z",
            "type": "AsymmetricX509Cert",
            "usage": "Verify",
            "key": "MIIDJzCCAg+gAw......CTxQvJ/zN3bafeesMSueR83hlCSyg==",
            "displayName": "CN=contoso"
        }

    ],
    "passwordCredentials": [
        {
            "customKeyIdentifier": "lY85bR8r6yWTW6jnciNEONwlVhDyiQjdVLgPDnkI5mA=",
            "keyId": "4c266507-3e74-4b91-aeba-18a25b450f6e",
            "endDateTime": "2022-01-27T19:40:33Z",
            "startDateTime": "2020-04-20T19:40:33Z",
            "secretText": "mypassword"
        }
    ]
}

Configurare una chiave di firma personalizzata con PowerShell

Usare PowerShell per creare un'istanza di un'applicazione client pubblica MSAL e usare il flusso di concessione del codice di autorizzazione per ottenere un token di accesso con autorizzazione delegata per Microsoft Graph. Usare il token di accesso per chiamare Microsoft Graph e configurare una chiave di firma personalizzata per l'entità servizio. Dopo aver configurato la chiave di firma personalizzata, il codice dell'applicazione deve convalidare la chiave di firma del token.

Per eseguire questo script, è necessario:

  • ID oggetto dell'entità servizio dell'applicazione, disponibile nel pannello Panoramica della voce dell'applicazione in Applicazioni aziendali nel portale di Azure.
  • Registrazione dell'app per accedere a un utente e ottenere un token di accesso per chiamare Microsoft Graph. Ottenere l'ID applicazione (client) di questa app nel pannello Panoramica della voce dell'applicazione in Registrazioni app nel portale di Azure. La registrazione dell'app deve avere la configurazione seguente:
    • URI di reindirizzamento "http://localhost" elencato nella configurazione della piattaforma applicazioni per dispositivi mobili e desktop .
    • Nelle autorizzazioni API, le autorizzazioni delegate di Microsoft Graph Application.ReadWrite.All e User.Read (assicurarsi di concedere Amministrazione il consenso a queste autorizzazioni).
  • Un utente che accede per ottenere il token di accesso di Microsoft Graph. L'utente deve essere uno dei seguenti ruoli amministrativi di Microsoft Entra (necessario per aggiornare l'entità servizio):
    • Amministratore applicazione cloud
    • Amministratore di applicazioni
    • Amministratore globale
  • Certificato da configurare come chiave di firma personalizzata per l'applicazione. È possibile creare un certificato autofirmato o ottenerlo dall'autorità di certificazione attendibile. Nello script vengono usati i componenti del certificato seguenti:
    • chiave pubblica (in genere un file di .cer)
    • chiave privata in formato PKCS#12 (nel file pfx)
    • password per la chiave privata (file pfx)

Importante

La chiave privata deve essere in formato PKCS#12 perché Microsoft Entra ID non supporta altri tipi di formato. L'uso del formato errato può generare l'errore "Certificato non valido: Il valore della chiave non è valido" quando si usa Microsoft Graph per APPLICARE PATCH all'entità servizio con un contenente keyCredentials le informazioni sul certificato.

$fqdn="fourthcoffeetest.onmicrosoft.com" # this is used for the 'issued to' and 'issued by' field of the certificate
$pwd="mypassword" # password for exporting the certificate private key
$location="C:\\temp" # path to folder where both the pfx and cer file will be written to

# Create a self-signed cert
$cert = New-SelfSignedCertificate -certstorelocation cert:\currentuser\my -DnsName $fqdn
$pwdSecure = ConvertTo-SecureString -String $pwd -Force -AsPlainText
$path = 'cert:\currentuser\my\' + $cert.Thumbprint
$cerFile = $location + "\\" + $fqdn + ".cer"
$pfxFile = $location + "\\" + $fqdn + ".pfx"
 
# Export the public and private keys
Export-PfxCertificate -cert $path -FilePath $pfxFile -Password $pwdSecure
Export-Certificate -cert $path -FilePath $cerFile

$ClientID = "<app-id>"
$loginURL       = "https://login.microsoftonline.com"
$tenantdomain   = "fourthcoffeetest.onmicrosoft.com"
$redirectURL = "http://localhost" # this reply URL is needed for PowerShell Core 
[string[]] $Scopes = "https://graph.microsoft.com/.default"
$pfxpath = $pfxFile # path to pfx file
$cerpath = $cerFile # path to cer file
$SPOID = "<service-principal-id>"
$graphuri = "https://graph.microsoft.com/v1.0/serviceprincipals/$SPOID"
$password = $pwd  # password for the pfx file
 
 
# choose the correct folder name for MSAL based on PowerShell version 5.1 (.Net) or PowerShell Core (.Net Core)
 
if ($PSVersionTable.PSVersion.Major -gt 5)
    { 
        $core = $true
        $foldername =  "netcoreapp2.1"
    }
else
    { 
        $core = $false
        $foldername = "net45"
    }
 
# Load the MSAL/microsoft.identity/client assembly -- needed once per PowerShell session
[System.Reflection.Assembly]::LoadFrom((Get-ChildItem C:/Users/<username>/.nuget/packages/microsoft.identity.client/4.32.1/lib/$foldername/Microsoft.Identity.Client.dll).fullname) | out-null
  
$global:app = $null
  
$ClientApplicationBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($ClientID)
[void]$ClientApplicationBuilder.WithAuthority($("$loginURL/$tenantdomain"))
[void]$ClientApplicationBuilder.WithRedirectUri($redirectURL)
 
$global:app = $ClientApplicationBuilder.Build()
  
Function Get-GraphAccessTokenFromMSAL {
    [Microsoft.Identity.Client.AuthenticationResult] $authResult  = $null
    $AquireTokenParameters = $global:app.AcquireTokenInteractive($Scopes)
    [IntPtr] $ParentWindow = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
    if ($ParentWindow)
    {
        [void]$AquireTokenParameters.WithParentActivityOrWindow($ParentWindow)
    }
    try {
        $authResult = $AquireTokenParameters.ExecuteAsync().GetAwaiter().GetResult()
    }
    catch {
        $ErrorMessage = $_.Exception.Message
        Write-Host $ErrorMessage
    }
     
    return $authResult
}
  
$myvar = Get-GraphAccessTokenFromMSAL
if ($myvar)
{
    $GraphAccessToken = $myvar.AccessToken
    Write-Host "Access Token: " $myvar.AccessToken
    #$GraphAccessToken = "eyJ0eXAiOiJKV1QiL ... iPxstltKQ"
    
 
    #  this is for PowerShell Core
    $Secure_String_Pwd = ConvertTo-SecureString $password -AsPlainText -Force
 
    # reading certificate files and creating Certificate Object
    if ($core)
    {
        $pfx_cert = get-content $pfxpath -AsByteStream -Raw
        $cer_cert = get-content $cerpath -AsByteStream -Raw
        $cert = Get-PfxCertificate -FilePath $pfxpath -Password $Secure_String_Pwd
    }
    else
    {
        $pfx_cert = get-content $pfxpath -Encoding Byte
        $cer_cert = get-content $cerpath -Encoding Byte
        # Write-Host "Enter password for the pfx file..."
        # calling Get-PfxCertificate in PowerShell 5.1 prompts for password
        # $cert = Get-PfxCertificate -FilePath $pfxpath
        $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfxpath, $password)
    }
 
    # base 64 encode the private key and public key
    $base64pfx = [System.Convert]::ToBase64String($pfx_cert)
    $base64cer = [System.Convert]::ToBase64String($cer_cert)
 
    # getting id for the keyCredential object
    $guid1 = New-Guid
    $guid2 = New-Guid
 
    # get the custom key identifier from the certificate thumbprint:
    $hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
    $hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($cert.Thumbprint))
    $customKeyIdentifier = [System.Convert]::ToBase64String($hash)
 
    # get end date and start date for our keycredentials
    $endDateTime = ($cert.NotAfter).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
    $startDateTime = ($cert.NotBefore).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
 
    # building our json payload
    $object = [ordered]@{    
    keyCredentials = @(       
         [ordered]@{            
            customKeyIdentifier = $customKeyIdentifier
            endDateTime = $endDateTime
            keyId = $guid1
            startDateTime = $startDateTime 
            type = "X509CertAndPassword"
            usage = "Sign"
            key = $base64pfx
            displayName = "CN=fourthcoffeetest" 
        },
        [ordered]@{            
            customKeyIdentifier = $customKeyIdentifier
            endDateTime = $endDateTime
            keyId = $guid2
            startDateTime = $startDateTime 
            type = "AsymmetricX509Cert"
            usage = "Verify"
            key = $base64cer
            displayName = "CN=fourthcoffeetest"   
        }
        )  
    passwordCredentials = @(
        [ordered]@{
            customKeyIdentifier = $customKeyIdentifier
            keyId = $guid1           
            endDateTime = $endDateTime
            startDateTime = $startDateTime
            secretText = $password
        }
    )
    }
 
    $json = $object | ConvertTo-Json -Depth 99
    Write-Host "JSON Payload:"
    Write-Output $json
 
    # Request Header
    $Header = @{}
    $Header.Add("Authorization","Bearer $($GraphAccessToken)")
    $Header.Add("Content-Type","application/json")
 
    try 
    {
        Invoke-RestMethod -Uri $graphuri -Method "PATCH" -Headers $Header -Body $json
    } 
    catch 
    {
        # Dig into the exception to get the Response details.
        # Note that value__ is not a typo.
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    }
 
    Write-Host "Complete Request"
}
else
{
    Write-Host "Fail to get Access Token"
}

Convalidare la chiave di firma del token

Per le app con mapping delle attestazioni abilitato è necessario convalidare le chiavi di firma del token aggiungendo appid={client_id} alle richieste di metadati OpenID Connect. Nell'esempio seguente viene illustrato il formato del documento di metadati OpenID Connessione da usare:

https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}

Aggiornare il manifesto dell'applicazione

Per le app a tenant singolo, è possibile impostare la acceptMappedClaims proprietà su true nel manifesto dell'applicazione. Come documentato nel apiApplication tipo di risorsa. L'impostazione della proprietà consente a un'applicazione di usare il mapping delle attestazioni senza specificare una chiave di firma personalizzata.

Avviso

Non impostare la proprietà acceptMappedClaims su true per le app multi-tenant, che possono consentire agli attori malintenzionati di creare criteri di mapping delle attestazioni per l'app.

Il gruppo di destinatari del token richiesto deve usare un nome di dominio verificato del tenant di Microsoft Entra, il che significa che è necessario impostare Application ID URI (rappresentato da identifierUris nel manifesto dell'applicazione) ad esempio https://contoso.com/my-api su o (semplicemente usando il nome del tenant predefinito). https://contoso.onmicrosoft.com/my-api

Se non si usa un dominio verificato, Microsoft Entra ID restituisce un AADSTS501461 codice di errore con il messaggio "_AcceptMappedClaims è supportato solo per un gruppo di destinatari del token corrispondente al GUID dell'applicazione o a un gruppo di destinatari all'interno dei domini verificati del tenant. Modificare l'identificatore della risorsa o usare una chiave di firma specifica dell'applicazione."

Opzioni avanzate per le attestazioni

Configurare le opzioni avanzate delle attestazioni per le applicazioni OIDC per esporre la stessa attestazione dei token SAML. Per le applicazioni che intendono usare la stessa attestazione sia per i token di risposta SAML2.0 che per i token di risposta OIDC.

Configurare le opzioni avanzate delle attestazioni selezionando la casella in Opzioni attestazioni avanzate nel pannello Gestisci attestazioni .

Passaggi successivi