Esercitazione: Aggiungere l'accesso all'app Android usando l'autenticazione nativa
Questa esercitazione illustra come accedere e disconnettere un utente con passcode monouso tramite posta elettronica o nome utente e password nell'app per dispositivi mobili Android usando l'autenticazione nativa.
In questa esercitazione apprenderai a:
- Far accedere un utente usando il passcode monouso o il nome utente (e-mail) e la password.
- Disconnettere un utente.
- Gestire gli errori di accesso
Prerequisiti
- Completare i passaggi descritti in Esercitazione: Preparare l'app Android per l'autenticazione nativa. Questa esercitazione illustra come preparare il progetto Android o l'app per l'autenticazione nativa.
Accesso di un utente
Per accedere a un utente usando il passcode monouso, raccogliere il messaggio di posta elettronica e inviare un messaggio di posta elettronica contenente un passcode monouso per consentire all'utente di verificare il proprio messaggio di posta elettronica. Quando l'utente immette un passcode monouso valido, l'app gli consente di accedere.
Per accedere a un utente usando il nome utente (indirizzo di posta elettronica) e la password, raccogliere l'indirizzo di posta elettronica e la password dall'utente. Se il nome utente e la password sono validi, l'app consente all'utente di accedere.
Per far accedere un utente, è necessario:
Creare un'interfaccia utente (IU) per:
- Acquisire un’e-mail dall'utente. Aggiungere la convalida agli input per accertarsi che l'utente immetta un indirizzo di posta elettronica valido.
- Acquisire una password se si effettua l'iscrizione con il nome utente (e-mail) e la password.
- Raccogliere un passcode monouso tramite posta elettronica dall'utente se si accede con passcode monouso tramite posta elettronica.
- Inviare nuovamente il passcode monouso (scelta consigliata) se si accede con passcode monouso tramite posta elettronica.
Nell'interfaccia utente aggiungere un pulsante, la cui selezione avvia un accesso, come illustrato nel frammento di codice seguente:
CoroutineScope(Dispatchers.Main).launch { val parameters = NativeAuthSignInParameters(username = email) // Assign 'password' param if you sign in with username (email) and password // parameters.password = password val actionResult: SignInResult = authClient.signIn(parameters) if (actionResult is SignInResult.CodeRequired) { val nextState = actionResult.nextState val submitCodeActionResult = nextState.submitCode( code = code ) if (submitCodeActionResult is SignInResult.Complete) { // Handle sign in success val accountState = submitCodeActionResult.resultValue val getAccessTokenParameters = NativeAuthGetAccessTokenParameters() val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters) if (accessTokenResult is GetAccessTokenResult.Complete) { val accessToken = accessTokenResult.resultValue.accessToken val idToken = accountState.getIdToken() } } } }
Se l'utente non deve inviare un passcode, ad esempio quando un utente accede con posta elettronica e password, usare il frammento di codice seguente:
CoroutineScope(Dispatchers.Main).launch { val parameters = NativeAuthSignInParameters(username = email) parameters.password = password val actionResult: SignInResult = authClient.signIn(parameters) if (actionResult is SignInResult.Complete) -> { // Handle sign in success val accountState = actionResult.resultValue val getAccessTokenParameters = NativeAuthGetAccessTokenParameters() val accessTokenResult = accountState.getAccessToken(getAccessTokenParameters) if (accessTokenResult is GetAccessTokenResult.Complete) { val accessToken = accessTokenResult.resultValue.accessToken val idToken = accountState.getIdToken() } } }
- Per avviare il flusso di accesso, usare il metodo
signIn(parameters)
dell'SDK. - Istanza della classe
NativeAuthSignInParameters
contenente ilusername
che corrisponde all'indirizzo di posta elettronica raccolto dall'utente. - Se il metodo di accesso è nome utente (indirizzo di posta elettronica) e password, il parametro
password
del metodo è la password che si raccoglie dall'utente. - Nello scenario più comune, il
signIn(parameters)
restituisce un risultato,SignInResult.CodeRequired
, che indica che l'SDK prevede che l'app invii il passcode monouso di posta elettronica inviato all'indirizzo di posta elettronica dell'utente. - L'oggetto
SignInResult.CodeRequired
contiene un nuovo riferimento di stato, che è possibile recuperare tramiteactionResult.nextState
. - Il nuovo stato consente di accedere a due nuovi metodi:
-
submitCode()
invia l’e-mail passcode monouso che l'app acquisisce dall'utente. -
resendCode()
invia nuovamente l’e-mail passcode monouso se l'utente non riceve il codice.
-
- Per avviare il flusso di accesso, usare il metodo
Gestire gli errori di accesso
Durante l'accesso, non tutte le azioni hanno esito positivo. Ad esempio, l'utente potrebbe tentare di accedere con un indirizzo di posta elettronica che non esiste o inviare un codice non valido.
Gestire gli errori di avvio dell'accesso
Per gestire gli errori nel metodo signIn(parameters)
, usare il frammento di codice seguente:
val parameters = NativeAuthSignInParameters(username = email)
// Assign 'password' param if you sign in with username (email) and password
// parameters.password = password
val actionResult: SignInResult = authClient.signIn(parameters)
if (actionResult is SignInResult.CodeRequired) {
// Next step: submit code
} else if (actionResult is SignInError) {
// Handle sign in errors
when {
actionResult.isUserNotFound() -> {
// Handle "user not found" error
}
actionResult.isAuthNotSupported() -> {
// Handle "authentication type not support" error
}
actionResult.isInvalidCredentials() -> {
// Handle specific errors
}
else -> {
// Handle other errors
}
}
}
-
SignInError
indica un risultato di azione non riuscito restituito dasignIn(parameters)
, pertanto il risultato dell'azione non include un riferimento al nuovo stato. - Se
actionResult is SignUpError
, Android SDK fornisce metodi di utilità per consentire di analizzare ulteriormente gli errori specifici:- Il metodo
isUserNotFound()
controlla se l'utente accede con un nome utente (indirizzo di posta elettronica) che non esiste. - Il metodo
isBrowserRequired()
controlla la necessità di un browser (fallback Web), per completare il flusso di autenticazione. Questo scenario si verifica quando l'autenticazione nativa non è sufficiente per completare il flusso di autenticazione. Ad esempio, un amministratore configura l’e-mail e la password come metodo di autenticazione, ma l'app non riesce a inviare la password come tipologia di verifica o semplicemente non la supporta. Usare la procedura descritta in Supportare il fallback Web nell'app Android per gestire lo scenario in cui si verifica. - Il metodo
isAuthNotSupported()
controlla se l'app invia un tipo di verifica non supportato da Microsoft Entra, ovvero un valore del tipo di verifica diverso da oob e password. Altre informazioni sulle tipologie di verifica. - Per l'accesso con nome utente (posta elettronica) e password, il metodo
isInvalidCredentials()
controlla se la combinazione di nome utente e password non è corretta.
- Il metodo
Gestire gli errori del codice di invio
Per gestire gli errori nel metodo submitCode()
, usare il frammento di codice seguente:
val submitCodeActionResult = nextState.submitCode(
code = code
)
if (submitCodeActionResult is SignInResult.Complete) {
// Sign in flow complete, handle success state.
} else if (submitCodeActionResult is SubmitCodeError && submitCodeActionResult.isInvalidCode()) {
// Handle "invalid code" error
}
- L'errore
SubmitCodeError
indica un risultato dell'azione non riuscita restituito dasubmitCode()
e quindi il risultato dell'azione non include un riferimento al nuovo stato. - Verifica
isInvalidCode()
la presenza dell'errore specifico. In questo caso, il riferimento allo stato precedente deve essere usato per ripetere l'azione.
Per recuperare il nuovo passcode monouso tramite posta elettronica, usare il frammento di codice seguente:
val submitCodeActionResult = nextState.submitCode(
code = code
)
if (submitCodeActionResult is SignInError && submitCodeActionResult.isInvalidCode) {
// Inform the user that the submitted code was incorrect or invalid, then ask them to input a new email one-time passcode
val newCode = retrieveNewCode()
nextState.submitCode(
code = newCode
)
}
Sono stati completati tutti i passaggi necessari per accedere correttamente a un utente nell'app. Compilare ed eseguire l'applicazione. Se tutto va bene, dovrebbe essere possibile fornire un messaggio di posta elettronica, ricevere un codice nel messaggio di posta elettronica e usarlo per accedere correttamente all'utente.
Leggere le attestazioni del token ID
Quando l'app ha acquisito un token ID, è possibile recuperare le attestazioni associate all'account corrente. A tale scopo, usare il frammento di codice seguente.
val preferredUsername = accountState.getClaims()?.get("preferred_username")
val city = accountState.getClaims()?.get("City")
val givenName = accountState.getClaims()?.get("given_name")
//custom attribute
val loyaltyNumber = accountState.getClaims()?.get("loyaltyNumber")
La chiave usata per accedere al valore dell'attestazione è il nome specificato quando si aggiunge l'attributo utente come attestazione token.
Per informazioni su come aggiungere attributi predefiniti e personalizzati a come attestazioni di token nell'articolo Aggiungere attributi utente alle attestazioni token.
Disconnessione di un utente
Per disconnettere un utente, è necessario rimuovere l'account attualmente archiviato nella cache.
Creare l'interfaccia utente personalizzata che include:
- Pulsante di disconnessione selezionato dall'utente per inviare una richiesta di disconnessione.
Per disconnettere un utente, usare il codice seguente:
private fun performSignOut(accountState: AccountState) { CoroutineScope(Dispatchers.Main).launch { val accountResult = authClient.getCurrentAccount() if (accountResult is GetAccountResult.AccountFound) { val signOutResult = accountResult.resultValue.signOut() if (signOutResult is SignOutResult.Complete) { // Show sign out successful UI } } } }
Gestire gli errori di disconnessura
Disconnettersi deve essere privo di errori. Se si verificano errori, esaminare il risultato dell'errore usando il frammento di codice seguente:
val actionResult = accountResult.signOut()
if (actionResult is SignOutResult.Complete) {
// Show sign out successful UI
} else {
// Handle errors
}
Assicurarsi di includere le istruzioni di importazione. Android Studio deve includere automaticamente le istruzioni di importazione.
Sono stati completati tutti i passaggi necessari per disconnettere correttamente un utente nell'app. Compilare ed eseguire l'applicazione. Se tutto va bene, si dovrebbe riuscire a selezionare il pulsante Disconnetti per una corretta disconnessione.
Configurare un provider di attestazioni personalizzato
Se si desidera aggiungere attestazioni da un sistema esterno al token rilasciato all'app, usare un provider di attestazioni personalizzato. Un provider di attestazioni personalizzato è costituito da un'estensione di autenticazione personalizzata che chiama un'API REST per recuperare le attestazioni da sistemi esterni.
Seguire la procedura descritta in Configurare un provider di attestazioni personalizzato per aggiungere attestazioni da un sistema esterno ai token di sicurezza.