I servizi mobili di Azure consentono di autenticare gli utenti dalle tue app di Windows universali. In questo tutorial, imparerai come:
ID utente
non esiste, e in caso contrario aggiorna l'utente esistenteI seguenti passaggi sono necessari per abilitare l'autenticazione nella tua app:
È necessario registrare l'app con un provider di identità e aggiungere le credenziali generate dal provider ai servizi mobili di Azure. Vediamo prima come registrare la tua app per l'accesso all'account Microsoft.
Per utilizzare Live Connect come provider di autenticazione per Servizi mobili di Azure, attenersi alla seguente procedura.
Apri un browser e vai al Dev Center per le app di Windows Store. Vai a Invia un'app pagina e clicca Nome dell'applicazione.
Prenota un Nome dell'applicazione e fare clic Salvare. L'app verrà elencata in Windows Store con questo nome.
Sul Servizi pagina, fare clic Servizi Live sotto Servizi mobili di Windows Azure.
Notare i valori di Identificativo cliente, Segreto del cliente, e Identificatore di sicurezza del pacchetto (SID). Avrai bisogno di questi valori più tardi.
Sotto Impostazioni API, fornire il seguente valore come Reindirizza URl e fare clic Salvare.
https: //.azure-mobile.net/login/microsoftaccount
Ciò consente l'autenticazione dell'account Microsoft per la tua app.
Dopo aver registrato l'app con il provider di identità, è necessario configurare i servizi mobili di Azure utilizzando il portale di gestione di Azure.
Accedere al portale di gestione di Azure, fare clic su Servizi mobili, e seleziona la tua app.
Sotto il Spingere scheda, immettere il Client Secret e SID del pacchetto valori e fare clic Salvare.
Sotto il Identità scheda, impostare il Identificativo cliente. Imposta anche il Client Secret e SID del pacchetto valori se non sono già impostati.
Ora sei pronto per utilizzare un account Microsoft per l'autenticazione nella tua app utilizzando Servizi mobili di Azure.
Utilizzando il portale di gestione di Azure, possiamo impostare le autorizzazioni della tabella per limitare l'accesso solo agli utenti registrati.
Sotto il Dati scheda nel portale di gestione di Azure, selezionare la tabella per cui si desidera modificare le autorizzazioni. In questo tutorial, stiamo modificando le autorizzazioni per UsersTable.
Sotto il permessi scheda, impostare tutte le autorizzazioni su Solo utenti autenticati e fare clic Salvare.
Quando l'app di Windows Store tenta di accedere a questa tabella, viene sollevata un'eccezione non gestita con un codice di stato 401 (Non autorizzato). Ciò accade perché l'app tenta di accedere a Servizi mobili di Azure come utente non autenticato.
Successivamente, dobbiamo configurare l'app WinRT di Windows Phone 8.1 per utilizzare i servizi mobili di Azure.
Questo passaggio si applica solo al provider di accesso all'account Microsoft. Registrando le informazioni sul pacchetto dell'app Windows Store con i Servizi mobili, il client è in grado di riutilizzare i dettagli di accesso di Microsoft per un'esperienza di single sign-on.
Fai clic destro sul progetto nel Esploratore di soluzioni, selezionare Memorizzare e fare clic Associa l'app allo Store. Nel Associa la tua app a Windows Store procedura guidata, fare clic registrati e accedi con il tuo account Microsoft. Seleziona l'app che hai registrato in precedenza e Socio con il negozio.
Le informazioni sulla registrazione di Windows Store richieste vengono quindi aggiunte al manifest dell'applicazione.
Quindi, aggiungi il Servizi mobili di Windows Azure SDK che utilizza il gestore pacchetti NuGet.
Il servizio mobile che hai creato nel portale di gestione di Azure deve essere collegato all'app. Fai clic destro sul progetto nel Esploratore di soluzioni e selezionare Servizi connessi sotto Inserisci.
Nel Responsabile del servizio finestra di dialogo che appare, scegli il servizio mobile che hai creato in precedenza e fai clic ok. Questo aggiunge un'istanza di servizio mobile in app.xaml.cs.
Definisci una classe UsersTable
i cui membri di dati rappresentano le colonne nella tabella. Dovrai aggiungere un riferimento alla libreria Json.NET nella tua app per usare il JsonProperty
classe.
class UsersTable [JsonProperty (PropertyName = "id")] stringa pubblica Id get; impostato; [JsonProperty (PropertyName = "userId")] public stringa UserID get; impostato; [JsonProperty (PropertyName = "user_email")] public string Email get; impostato; [JsonProperty (PropertyName = "profile_picture")] public stringa ProfilePicture get; impostato; [JsonProperty (PropertyName = "display_name")] public stringa DisplayName get; impostato;
Successivamente, aggiungeremo l'autenticazione dell'utente prima di richiedere qualsiasi risorsa dal servizio mobile.
Dichiarare una variabile membro globale per Pagina principale
classe per la memorizzazione dell'utente autenticato.
utente MobileServiceUser privato;
AuthenticateAsync
MetodoAggiungiamo un metodo che esegue il processo di autenticazione. Il LoginAsync
il metodo accetta il provider di identità come parametro e gestisce il flusso di autenticazione.
private async System.Threading.Tasks.Task AuthenticateAsync () user = attende App.MobileService.LoginAsync (MobileServiceAuthenticationProvider.MicrosoftAccount);
Su Windows Phone 8.1, è necessario gestire la risposta da WebAuthenticationBroker
. Aggiungiamo un OnActivated
metodo in app.xaml.cs per gestire questa risposta.
protetto override void OnActivated (IActivatedEventArgs args) #if WINDOWS_PHONE_APP if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation) App.MobileService.LoginComplete (args come WebAuthenticationBrokerContinuationEventArgs); #endif base.OnActivated (args);
Se la OnActivated
il metodo esiste già, basta aggiungere quanto sopra # if ... #endif
blocco di codice. Si noti che il LoginAsync
il metodo deve essere chiamato dopo il OnNavigated
il metodo è stato chiamato e dopo quello della pagina Caricato
l'evento è stato attivato.
Aggiungi un pulsante di accesso alla tua app MainPage.xaml e chiamare un metodo per autenticare l'utente quando si fa clic sul pulsante.
Al clic del pulsante, chiama il AuthenticateAsync
metodo e nascondere il pulsante di accesso se l'autenticazione ha esito positivo.
private async void ButtonLogin_Click (mittente dell'oggetto, RoutedEventArgs e) // Accedi all'utente e carica i dati dal servizio mobile. attende AuthenticateAsync (); // Nascondi il pulsante di accesso e carica gli elementi dal servizio mobile. this.ButtonLogin.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
AuthenticateAsync
MetodoNostro AuthenticateAsync
il metodo gestisce l'autenticazione degli utenti, ma possiamo aggiungere codice per gestire eccezioni e flussi alternativi. Aggiorniamo la funzione per chiamare iterativamente LoginAsync
metodo fino al utente
non è nullo
. In caso di autenticazione riuscita, mostriamo il ID utente
dell'utente autenticato. Una volta che l'utente ha effettuato l'accesso, l'app dovrebbe essere eseguita senza errori.
private async System.Threading.Tasks.Task AuthenticateAsync () while (utente == null) stringa di messaggi; prova utente = attendi App.MobileService.LoginAsync (MobileServiceAuthenticationProvider.MicrosoftAccount); message = string.Format ("Ora sei connesso - 0", user.UserId); catch (InvalidOperationException) message = "Accesso richiesto"; var dialog = new MessageDialog (message); dialog.Commands.Add (new UICommand ("OK")); attendere la finestra di dialogo. MostraAsync ();
Il AuthenticateAsync
La funzione richiede che il client contatti sia il provider di identità che il servizio mobile ogni volta che l'app viene avviata. Non è molto efficiente. Inoltre, se molti utenti utilizzano l'app nello stesso momento, è possibile che si verifichino problemi di caricamento.
Per rimediare a questo problema, possiamo memorizzare nella cache il token di autenticazione. Possiamo provare a usare il token di autenticazione memorizzato nella cache, ricadendo nel flusso di autenticazione predefinito se il token di autenticazione non è più valido.
private async System.Threading.Tasks.Task AuthenticateAsync (String provider) string message; // Utilizzare PasswordVault per archiviare e accedere in modo sicuro alle credenziali. PasswordVault vault = new PasswordVault (); Credenziale PasswordCredential = null; while (credential == null) try // Cerca di ottenere una credenziale esistente dal vault. credential = vault.FindAllByResource (provider) .FirstOrDefault (); catch (Exception) // Quando non ci sono risorse corrispondenti si verifica un errore, che ignoriamo. if (credential! = null) // Crea un utente dalle credenziali memorizzate. utente = nuovo MobileServiceUser (credential.UserName); credential.RetrievePassword (); user.MobileServiceAuthenticationToken = credential.Password; // Imposta l'utente dalle credenziali archiviate. App.MobileService.CurrentUser = utente; prova // Prova a restituire un elemento ora per determinare se la credenziale memorizzata nella cache è scaduta. attendi App.MobileService.GetTable() .Take (1) .ToListAsync (); catch (MobileServiceInvalidOperationException ex) if (ex.Response.StatusCode == System.Net.HttpStatusCode.Unauthorized) // Rimuovi la credenziale con il token scaduto. vault.Remove (credenziali); credential = null; Continua; else try // Accedi con il provider di identità. utente = attendi App.MobileService.LoginAsync (provider); // Crea e memorizza le credenziali dell'utente. credential = new PasswordCredential (provider, user.UserId, user.MobileServiceAuthenticationToken); vault.Add (credenziali); catch (MobileServiceInvalidOperationException ex) message = "Devi effettuare il login. Accesso richiesto"; message = string.Format ("Ora sei loggato - 0", user.UserId); var dialog = new MessageDialog (message); dialog.Commands.Add (new UICommand ("OK")); attendere la finestra di dialogo. MostraAsync ();
Il modificato AuthenticateAsync
la funzione tenta di utilizzare le credenziali memorizzate nel file PasswordVault
per accedere al servizio mobile. La seguente sequenza di eventi si verifica:
PasswordVault
.PasswordVault
non contiene credenziali, torniamo al flusso di autenticazione predefinito.Si noti che l'app verifica i token di autenticazione scaduti durante l'accesso. Tuttavia, i token di autenticazione possono scadere dopo l'autenticazione, quando l'utente sta utilizzando l'app. Un post sul blog MSDN spiega come gestire una situazione del genere.
Gli oggetti client non espongono tutte le informazioni dell'utente, ma sul server possiamo ottenere tutte le informazioni di cui abbiamo bisogno. Il Utente
oggetto, che viene passato a tutti gli script, ha a getIdentities
funzione che restituisce un oggetto con dati specifici del provider. Può essere usato per interrogare le informazioni dell'utente. Per un utente autenticato con un account Microsoft, l'oggetto viene restituito chiamando user.getIdentities
.
"microsoft": "userId": "MicrosoftAccount: my-actual-user-id", "accessToken": "the-actual-access-token"
Per ottenere le informazioni dell'utente, inviamo una richiesta a https://apis.live.net/v5.0/me/
, passando il token di accesso come parametro. La quantità di informazioni disponibili dai provider agli script utente è limitata. Questo è il risultato della richiesta al /me
endpoint:
"id": "my-live-id", "nome": "Vivek Maskara", "first_name": "Vivek", "last_name": "Maskara", "link": "https://profile.live .com / "," gender ": null," locale ":" en_US "," updated_time ":" 2015-03-10T16: 03: 43-08: 00 "
Ulteriori ambiti di autenticazione devono essere richiesti per ulteriori informazioni. I servizi mobili di Azure ci consentono di specificare ambiti personalizzati che vengono trasmessi ai provider di autenticazione quando si esegue l'autenticazione lato server.
Per impostazione predefinita, il login richiede solo il wl.basic
scopo. Possiamo ottenere maggiori informazioni sull'utente se impostiamo alcuni ambiti aggiuntivi. Richiediamo ora un ambito aggiuntivo dal login di Microsoft.
Sotto il Configurazione scheda del servizio mobile, impostare il MS_MicrosoftScope
nel Impostazioni dell'app.
Come risultato di questo cambiamento, otterrò le informazioni aggiuntive che ho richiesto dopo aver effettuato nuovamente l'accesso.
"id": "my-live-id", "nome": "Vivek Maskara", "first_name": "Vivek", "last_name": "Maskara", "link": "https://profile.live .com / "," gender ": null," email ": " preferito ":" [email protected] "," account ":" [email protected] "," personal ": null," business ": null, "locale": "en_US", "updated_time": "2015-03-10T16: 03: 43-08: 00"
Se l'utente ha effettuato l'accesso tramite un account Microsoft, invierà una richiesta alle API di Live Connect, passando il token memorizzato nell'oggetto Identità utente. Infine, analizzerà l'oggetto JSON che viene restituito e recupererà i dettagli del profilo utente.
user.getIdentities (success: function (identità) var url; var oauth = null; if (identities.microsoft) var liveAccessToken = identities.microsoft.accessToken; url = 'https://apis.live.net/v5 .0 / me /? Method = GET & access_token = '+ liveAccessToken; if (url) var requestCallback = function (err, resp, body) if (err || risp.statusCode! == 200) console.error ( 'Errore nell'invio dei dati al provider:', err); request.respond (statusCodes.INTERNAL_SERVER_ERROR, body); else try var userData = JSON.parse (body); item.userId = user.userId; item.display_name = userData.name; item.user_email = userData.emails ['account']; request.execute (); catch (ex) console.error ('Errore durante l'analisi della risposta dall'API del provider:', ex); rispondere (statusCodes.INTERNAL_SERVER_ERROR, ex); var req = require ('request'); var reqOptions = uri: url, header: Accept: "application / json"; req (reqOptions, requestCallback); else // Inserisci con nome utente predefinito request.execute (););
Ora dobbiamo modificare lo script di inserimento per inserire un nuovo record se un utente con il ID utente
non esiste Se un utente esiste, aggiorniamo quell'utente. È possibile utilizzare uno script di tabella sul lato server per verificare se esiste un record prima di completare l'operazione di inserimento.
Ecco uno script di esempio che controlla se uno degli elementi nella tabella ha una corrispondenza ID utente
valore e, se questo è il caso, non esegue un inserimento.
function insert (item, user, request) var table = tables.getTable ('UsersTable'); table.where (userId: user.userId). read (success: upsertItem); function upsertItem (existingItems) if (existingItems.length === 0) request.execute (); else item.id = existingItems [0] .id; table.update (item, success: function (updatedItem) request.respond (200, updatedItem));
Ora possiamo combinare entrambi gli script per costruire il nostro script di inserimento finale per UsersTable. Sotto il copione scheda di UsersTable, sostituire lo script di inserimento con il seguente script:
function insert (item, user, request) item.display_name = ""; // default var table = tables.getTable ('UsersTable'); table.where (userId: user.userId). read (success: upsertItem); function upsertItem (existingItems) if (existingItems.length === 0) user.getIdentities (success: function (identità) var url; var oauth = null; if (identities.microsoft) var liveAccessToken = identities.microsoft.accessToken; url = 'https: // apis .live.net / v5.0 / me /? method = GET & access_token = '+ liveAccessToken; if (url) var requestCallback = function (err, resp, body) if (err || risp.statusCode! == 200 ) console.error ('Errore nell'invio dei dati al provider:', err); request.respond (statusCodes.INTERNAL_SERVER_ERROR, body); else try var userData = JSON.parse (body); item.userId = user .userId; item.display_name = userData.name; item.user_email = userData.emails ['account']; request.execute (); catch (ex) console.error ('Errore durante l'analisi della risposta dall'API del provider:' , ex); request.respond (statusCodes.INTERNAL_SERVER_ERROR, ex); var req = requir e ( 'richiesta'); var reqOptions = uri: url, header: Accept: "application / json"; req (reqOptions, requestCallback); else // Inserisci con nome utente predefinito request.execute (); ); else // abbiamo aggiornato l'utente con i valori esistenti ma potresti inserire qui nuovi valori. item.id = existingItems [0] .id; item.userId = existingItems [0] .userId; item.display_name = existingItems [0] .display_name; item.user_email = existingItems [0] .user_email; item.profile_picture = existingItems [0] .profile_picture; table.update (item, success: function (updatedItem) request.respond (200, updatedItem));
Ora che abbiamo aggiornato lo script di inserimento, qualsiasi chiamata per un'operazione di inserimento aggiungerà un nuovo record se un utente con uno specifico ID utente
non esiste Inoltre, l'elemento inserito viene aggiornato con le informazioni dell'utente ID utente
, nome
, e e-mail
.
Ho aggiunto un metodo InsertUser
, che accetta un parametro utente
di tipo UsersTable
e lo inserisce nel tavolo.
private async Task InsertUser (UsersTable utente) waititTable.InsertAsync (utente);
Dopo la chiamata al AuthenticateAsync
metodo sul tasto clic, chiamo il InsertUser
metodo per aggiungere l'utente a UsersTable
.
attendere InsertUser (new UserTable ProfilePicture = string.Empty);
Puoi eseguire l'app nell'emulatore per vedere se funziona. Quando si accede per la seconda volta, l'app utilizza il token di autenticazione memorizzato nella cache anziché presentare la schermata di accesso.
L'autenticazione degli utenti per diversi provider di identità tramite Azure Mobile Services è abbastanza semplice. In questo tutorial, ho mostrato come utilizzare un account Microsoft per l'autenticazione. La procedura per utilizzare altri provider di identità è la stessa. Solo il fornitore
parametro deve essere modificato nel AuthenticateAsync
chiamata. Si consiglia di memorizzare nella cache il token di autenticazione in modo che l'utente possa sperimentare il single sign-on.
È possibile richiedere ulteriori ambiti di autenticazione per recuperare più informazioni sull'utente. Questo articolo MSDN spiega come può essere fatto per vari provider di identità. Sentiti libero di scaricare i file sorgente del tutorial come riferimento. Ricordarsi di configurare l'app per utilizzare Servizi mobili di Azure prima di distribuirla.