Configurazione di un sito Web che usa i servizi per le applicazioni (VB)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenza ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare la ASP.NET Identity Platform anziché i provider di appartenenza in primo piano al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :

  • Prestazioni migliori
  • Miglioramento dell'estendibilità e della testability
  • Supporto per OAuth, OpenID Connect e autenticazione a due fattori
  • Supporto delle identità basate sulle attestazioni
  • Interoperabilità migliore con ASP.Net Core

ASP.NET versione 2.0 ha introdotto una serie di servizi applicazioni, che fanno parte di .NET Framework e fungono da suite di servizi a blocchi predefiniti che è possibile usare per aggiungere funzionalità avanzate all'applicazione Web. Questa esercitazione illustra come configurare un sito Web nell'ambiente di produzione per usare i servizi applicazioni e risolvere i problemi comuni relativi alla gestione degli account utente e dei ruoli nell'ambiente di produzione.

Introduzione

ASP.NET versione 2.0 ha introdotto una serie di servizi applicazioni, che fanno parte di .NET Framework e fungono da suite di servizi a blocchi predefiniti che è possibile usare per aggiungere funzionalità avanzate all'applicazione Web. I servizi dell'applicazione includono:

  • Appartenenza : un'API per la creazione e la gestione degli account utente.
  • Ruoli : un'API per categorizzare gli utenti in gruppi.
  • Profilo : un'API per l'archiviazione di contenuti personalizzati e specifici dell'utente.
  • Mappa siti: un'API per la definizione di una struttura logica del sito sotto forma di una gerarchia, che può quindi essere visualizzata tramite i controlli di spostamento, ad esempio menu e breadcrumb.
  • Personalizzazione : un'API per la gestione delle preferenze di personalizzazione, spesso usata con WebParts.
  • Monitoraggio dell'integrità : un'API per il monitoraggio delle prestazioni, della sicurezza, degli errori e delle altre metriche di integrità del sistema per un'applicazione Web in esecuzione.

Le API dei servizi applicazioni non sono associate a un'implementazione specifica. In alternativa, si indicare ai servizi dell'applicazione di usare un determinato provider e che il provider implementa il servizio usando una particolare tecnologia. I provider più comunemente usati per le applicazioni Web basate su Internet ospitate in una società di hosting Web sono i provider che usano un'implementazione del database SQL Server. Ad esempio, è SqlMembershipProvider un provider per l'API Appartenenza che archivia le informazioni sull'account utente in un database di microsoft SQL Server.

L'uso dei servizi applicazione e dei provider di SQL Server aggiunge alcuni problemi durante la distribuzione dell'applicazione. Per iniziare, gli oggetti di database dei servizi applicazioni devono essere creati correttamente nei database di sviluppo e di produzione e inizializzati in modo appropriato. Esistono anche impostazioni di configurazione importanti che devono essere effettuate.

Nota

Le API dei servizi applicazioni sono state progettate usando il modello provider, un modello di progettazione che consente di fornire i dettagli dell'implementazione di un'API in fase di esecuzione. .NET Framework viene fornito con diversi provider di servizi applicazioni che possono essere usati, ad esempio e SqlMembershipProviderSqlRoleProvider, che sono provider per le API appartenenza e ruoli che usano un'implementazione del database SQL Server. È anche possibile creare e collegare un provider personalizzato. In effetti, l'applicazione Web Book Reviews contiene già un provider personalizzato per l'API Mappa siti (ReviewSiteMapProvider), che costruisce la mappa del sito dai dati nei dati nel Genres database e Books tabelle.

Questa esercitazione inizia con un'occhiata alla modalità di estensione dell'applicazione Web Recensioni libro per usare le API Appartenenza e ruoli. Illustra quindi la distribuzione di un'applicazione Web che usa i servizi applicazioni con un'implementazione del database SQL Server e conclude risolvendo i problemi comuni relativi alla gestione degli account utente e dei ruoli nell'ambiente di produzione.

Aggiornamenti all'applicazione Recensioni libro

Negli ultimi due esercitazioni l'applicazione Web Book Reviews è stata aggiornata da un sito Web statico a un'applicazione Web dinamica e basata sui dati completa con un set di pagine di amministrazione per la gestione di generi e recensioni. Tuttavia, questa sezione di amministrazione non è attualmente protetta: qualsiasi utente che conosce (o indovina) l'URL della pagina di amministrazione può valsare e creare, modificare o eliminare recensioni nel sito. Un modo comune per proteggere determinate parti di un sito Web consiste nell'implementare gli account utente e quindi usare le regole di autorizzazione url per limitare l'accesso a determinati utenti o ruoli. L'applicazione Web Book Reviews disponibile per il download con questa esercitazione supporta account utente e ruoli. Ha un singolo ruolo definito Amministrazione e solo gli utenti in questo ruolo possono accedere alle pagine di amministrazione.

Nota

Ho creato tre account utente nell'applicazione Web Book Reviews: Scott, Jisun e Alice. Tutti e tre gli utenti hanno la stessa password: password! Scott e Jisun sono nel ruolo Amministrazione, Alice non è. Le pagine non di amministrazione del sito sono ancora accessibili agli utenti anonimi. In questo caso, non è necessario accedere per visitare il sito, a meno che non si voglia amministrarla, nel qual caso è necessario accedere come utente nel ruolo di Amministrazione.

La pagina master dell'applicazione Book Reviews è stata aggiornata per includere un'interfaccia utente diversa per gli utenti autenticati e anonimi. Se un utente anonimo visita il sito che vede un collegamento Di accesso nell'angolo superiore destro. Un utente autenticato visualizza il messaggio "Benvenuto, nome utente!" e un collegamento per disconnettersi. È disponibile anche una pagina di accesso (~/Login.aspx), che contiene un controllo Web di accesso che fornisce l'interfaccia utente e la logica per l'autenticazione di un visitatore. Solo gli amministratori possono creare nuovi account. Sono disponibili pagine per la creazione e la gestione degli account utente nella ~/Admin cartella.

Configurazione delle API di appartenenza e ruoli

L'applicazione Web Book Reviews usa le API Appartenenza e Ruoli per supportare gli account utente e raggruppare tali utenti in ruoli (ovvero il ruolo Amministrazione). Le SqlMembershipProvider classi e SqlRoleProvider provider vengono usate perché si vogliono archiviare informazioni sull'account e sul ruolo in un database SQL Server.

Nota

Questa esercitazione non è destinata a essere un esame dettagliato alla configurazione di un'applicazione Web per supportare le API appartenenza e ruoli. Per un'analisi approfondita di queste API e i passaggi da eseguire per configurare un sito Web da usare, leggere le esercitazioni sulla sicurezza del sito Web.

Per usare i servizi dell'applicazione con un database SQL Server, è prima necessario aggiungere gli oggetti di database usati da questi provider al database in cui si vogliono archiviare l'account utente e le informazioni sul ruolo. Questi oggetti di database necessari includono un'ampia gamma di tabelle, viste e stored procedure. A meno che non sia specificato in caso contrario, le SqlMembershipProvider classi e SqlRoleProvider provider usano un database SQL Server Express Edition denominato ASPNETDB nella cartella dell'applicazioneApp_Data. Se tale database non esiste, viene creato automaticamente con gli oggetti di database necessari da questi provider in fase di esecuzione.

È possibile, e in genere ideale, creare gli oggetti di database dei servizi applicazioni nello stesso database in cui vengono archiviati i dati specifici dell'applicazione del sito Web. .NET Framework viene fornito con uno strumento denominato aspnet_regsql.exe che installa gli oggetti di database in un database specificato. Sono andato avanti e usato questo strumento per aggiungere questi oggetti al Reviews.mdf database nella App_Data cartella (il database di sviluppo). Verrà illustrato come usare questo strumento più avanti in questa esercitazione quando si aggiungono questi oggetti al database di produzione.

Se si aggiungono gli oggetti di database dei servizi applicazioni a un database diverso ASPNETDB da quello necessario per personalizzare le configurazioni delle SqlMembershipProvider classi provider e SqlRoleProvider in modo che usino il database appropriato. Per personalizzare il provider di appartenenza aggiungere un <elemento di appartenenza> all'interno della <system.web> sezione in Web.config; usare l'elemento roleManager> per configurare il< provider Ruoli. Il frammento di codice seguente viene tratto dall'applicazione Recensioni libro e Web.config mostra le impostazioni di configurazione per le API Appartenenza e ruoli. Si noti che entrambi registrano un nuovo provider ReviewMembership e ReviewRole che usano rispettivamente i SqlMembershipProvider provider e SqlRoleProvider .

<configuration>
    <system.web>
        ...

        <membership defaultProvider="ReviewMembership">
            <providers>
                <clear />

                <add type="System.Web.Security.SqlMembershipProvider" 
                     name="ReviewMembership" 
                     connectionStringName="ReviewsConnectionString" 
                     applicationName="BookReviews" />
            </providers>
        </membership>

        <roleManager enabled="true" defaultProvider="ReviewRole">
            <providers>
                <clear />

                <add type="System.Web.Security.SqlRoleProvider" 
                     name="ReviewRole" 
                     connectionStringName="ReviewsConnectionString" 
                     applicationName="BookReviews" />
            </providers>
        </roleManager>

        ...
    </system.web>
</configuration>

L'elemento Web.config del <authentication> file è stato configurato anche per supportare l'autenticazione basata su moduli.

<configuration>
    <system.web>
        ...

        <authentication mode="Forms" />

        ...
    </system.web>
</configuration>

Limitazione dell'accesso alle pagine di amministrazione

ASP.NET semplifica la concessione o la negazione dell'accesso a un determinato file o a una determinata cartella da parte dell'utente o dal ruolo tramite la relativa funzionalità di autorizzazione URL . È stata illustrata brevemente l'autorizzazione URL nell'esercitazione Relativa alle differenze principali tra IIS e ASP.NET Development Server e è stato illustrato come IIS e il ASP.NET Development Server applicano regole di autorizzazione URL in modo diverso per il contenuto statico rispetto al contenuto dinamico. Poiché si vuole impedire l'accesso alla ~/Admin cartella, ad eccezione di tali utenti nel ruolo Amministrazione, è necessario aggiungere regole di autorizzazione URL a questa cartella. In particolare, le regole di autorizzazione URL devono consentire agli utenti nel ruolo Amministrazione e negare tutti gli altri utenti. Questa operazione viene eseguita aggiungendo un Web.config file alla ~/Admin cartella con il contenuto seguente:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <authorization>
            <allow roles="Admin" />
            <deny users="*" />
        </authorization>
    </system.web>
</configuration>

Per altre informazioni sulla funzionalità di autorizzazione dell'URL di ASP.NET e su come usarla per specificare le regole di autorizzazione per gli utenti e per i ruoli, assicurarsi di leggere le esercitazioni sull'autorizzazione basata su utenti e autorizzazioni basate su ruoli dalle esercitazioni sulla sicurezza del sito Web.

Distribuzione di un'applicazione Web che usa servizi applicazioni

Quando si distribuisce un sito Web che usa i servizi applicazione e un provider che archivia le informazioni sui servizi applicazione in un database, è imperativo che gli oggetti di database necessari dai servizi applicazione vengano creati nel database di produzione. Inizialmente il database di produzione non contiene questi oggetti, quindi quando l'applicazione viene prima distribuita (o quando viene distribuita per la prima volta dopo l'aggiunta dei servizi applicazione), è necessario eseguire passaggi aggiuntivi per ottenere questi oggetti di database necessari nel database di produzione.

Un'altra sfida può verificarsi quando si distribuisce un sito Web che usa i servizi applicazioni se si intende replicare gli account utente creati nell'ambiente di sviluppo nell'ambiente di produzione. A seconda della configurazione appartenenza e ruoli, è possibile che anche se si copiano correttamente gli account utente creati nell'ambiente di sviluppo nel database di produzione, questi utenti non possono accedere all'applicazione Web in produzione. Si esaminerà la causa di questo problema e si esaminerà come evitare che si verifichi.

ASP.NET viene fornito con un bel strumento di amministrazione siti Web (WSAT) che può essere avviato da Visual Studio e consente di gestire l'account utente, i ruoli e le regole di autorizzazione tramite un'interfaccia basata sul Web. Sfortunatamente, il servizio WSAT funziona solo per i siti Web locali, ovvero non può essere usato per gestire in remoto gli account utente, i ruoli e le regole di autorizzazione per l'applicazione Web nell'ambiente di produzione. Verranno esaminati diversi modi per implementare il comportamento simile a WSAT dal sito Web di produzione.

Aggiunta degli oggetti di database tramite aspnet_regsql.exe

L'esercitazione Sulla distribuzione di un database ha illustrato come copiare le tabelle e i dati dal database di sviluppo al database di produzione e queste tecniche possono essere certamente usate per copiare gli oggetti di database dei servizi applicazioni nel database di produzione. Un'altra opzione è lo aspnet_regsql.exe strumento, che aggiunge o rimuove gli oggetti di database dei servizi applicazioni da un database.

Nota

Lo aspnet_regsql.exe strumento crea gli oggetti di database in un database specificato. Non esegue la migrazione dei dati in tali oggetti di database dal database di sviluppo al database di produzione. Se si intende copiare l'account utente e le informazioni sul ruolo nel database di sviluppo nel database di produzione, usare le tecniche descritte nell'esercitazione Distribuzione di un database.

Esaminare come aggiungere gli oggetti di database al database di produzione usando lo aspnet_regsql.exe strumento . Iniziare aprendo Esplora risorse e passando alla directory .NET Framework versione 2.0 nel computer, %WINDIR%\ Microsoft.NET\Framework\v2.0.50727. C'è da trovare lo aspnet_regsql.exe strumento. Questo strumento può essere usato dalla riga di comando, ma include anche un'interfaccia utente grafica; fare doppio clic sul file per avviare il aspnet_regsql.exe componente grafico.

Lo strumento inizia visualizzando una schermata iniziale che spiega lo scopo. Fare clic su Avanti per passare alla schermata "Seleziona un'opzione di installazione", visualizzata nella figura 1. Da qui è possibile scegliere di aggiungere gli oggetti di database dei servizi applicazioni o rimuoverli da un database. Poiché si vogliono aggiungere questi oggetti al database di produzione, selezionare l'opzione "Configura SQL Server per i servizi dell'applicazione" e fare clic su Avanti.

Scegliere di configurare SQL Server per i servizi applicazioni

Figura 1: Scegliere di configurare SQL Server per i servizi applicazione (fare clic per visualizzare l'immagine a dimensione intera)

Nella schermata "Seleziona server e database" vengono richieste informazioni per la connessione al database. Immettere il server di database, le credenziali di sicurezza e il nome del database fornito dall'azienda di hosting Web e fare clic su Avanti.

Nota

Dopo aver immesso il server di database e le credenziali, è possibile che venga visualizzato un errore durante l'espansione dell'elenco a discesa del database. Lo aspnet_regsql.exe strumento esegue una query sulla sysdatabases tabella di sistema per recuperare un elenco di database nel server, ma alcune società di hosting Web bloccano i server di database in modo che queste informazioni non siano disponibili pubblicamente. Se viene visualizzato questo errore, è possibile digitare il nome del database direttamente nell'elenco a discesa.

Specificare lo strumento con le informazioni di connessione del database

Figura 2: Specificare lo strumento con le informazioni di connessione del database (fare clic per visualizzare l'immagine a dimensione intera)

Nella schermata successiva vengono riepilogate le azioni che stanno per essere eseguite, vale a dire che gli oggetti di database dei servizi applicazioni verranno aggiunti al database specificato. Fare clic su Avanti per completare questa azione. Dopo alcuni istanti, viene visualizzata la schermata finale, notando che gli oggetti di database sono stati aggiunti (vedere la figura 3).

Successo! Gli oggetti di database di Application Services sono stati aggiunti al database di produzione

Figura 3: Operazione riuscita Gli oggetti di database di Application Services sono stati aggiunti al database di produzione (fare clic per visualizzare l'immagine a dimensione intera)

Per verificare che gli oggetti di database dei servizi applicazione siano stati aggiunti correttamente al database di produzione, aprire SQL Server Management Studio e connettersi al database di produzione. Come illustrato nella figura 4, dovrebbero essere visualizzate le tabelle di database dei servizi applicazioni nel database, aspnet_Applications, aspnet_Membership, aspnet_Userse così via.

Verificare che gli oggetti di database siano stati aggiunti al database di produzione

Figura 4: Verificare che gli oggetti di database siano stati aggiunti al database di produzione (fare clic per visualizzare l'immagine a dimensione intera)

Sarà necessario usare lo strumento solo quando si distribuisce l'applicazione aspnet_regsql.exe Web per la prima volta o per la prima volta dopo l'avvio dell'uso dei servizi dell'applicazione. Una volta che questi oggetti di database si trovano nel database di produzione, non dovranno essere aggiunti nuovamente o modificati.

Copia di account utente da sviluppo a produzione

Quando si usano le SqlMembershipProvider classi del provider e SqlRoleProvider per archiviare le informazioni sui servizi dell'applicazione in un database SQL Server, le informazioni sull'account utente e sul ruolo vengono archiviate in un'ampia gamma di tabelle di database, tra cui aspnet_Users, aspnet_Membershipaspnet_Roles, e aspnet_UsersInRoles, tra le altre. Se durante lo sviluppo si creano account utente nell'ambiente di sviluppo, è possibile replicare tali account utente nell'ambiente di produzione copiando i record corrispondenti dalle tabelle di database applicabili. Se è stata usata la Pubblicazione guidata database per distribuire gli oggetti di database dei servizi applicazioni, è possibile che sia stata anche selezionata la copia dei record, il che comporta la creazione di account utente in fase di sviluppo anche nell'ambiente di produzione. Tuttavia, a seconda delle impostazioni di configurazione, è possibile che gli utenti i cui account siano stati creati in fase di sviluppo e copiati nell'ambiente di produzione non siano in grado di accedere dal sito Web di produzione. Quali sono i vantaggi?

Le SqlMembershipProvider classi di provider e SqlRoleProvider sono state progettate in modo che un singolo database possa fungere da archivio utente per più applicazioni, in cui ogni applicazione potrebbe, in teoria, avere utenti con nomi utente e ruoli sovrapposti con lo stesso nome. Per consentire questa flessibilità, il database mantiene un elenco di applicazioni nella aspnet_Applications tabella e ogni utente è associato a una di queste applicazioni. In particolare, la aspnet_Users tabella include una ApplicationId colonna che collega ogni utente a un record nella aspnet_Applications tabella.

Oltre alla ApplicationId colonna, la aspnet_Applications tabella include anche una ApplicationName colonna che fornisce un nome più descrittivo per l'applicazione. Quando un sito Web tenta di usare un account utente, ad esempio la convalida delle credenziali di un utente dalla pagina di accesso, deve indicare alla classe quale SqlMembershipProvider applicazione usare. Questa operazione viene in genere eseguita specificando il nome dell'applicazione e questo valore deriva dalla configurazione del provider in Web.config , in particolare tramite l'attributo applicationName .

Ma cosa accade se l'attributo applicationName non è specificato in Web.config? In tal caso, il sistema di appartenenza usa il percorso radice dell'applicazione come applicationName valore. Se l'attributo applicationName non è impostato in modo esplicito in Web.config, è possibile che l'ambiente di sviluppo e l'ambiente di produzione usino una radice dell'applicazione diversa e quindi saranno associati a nomi di applicazione diversi nei servizi dell'applicazione. Se si verifica una mancata corrispondenza, gli utenti creati nell'ambiente di sviluppo avranno un ApplicationId valore che non corrisponde al ApplicationId valore per l'ambiente di produzione. Il risultato netto è che questi utenti non saranno in grado di accedere.

Nota

Se ci si trova in questa situazione, con gli account utente copiati nell'ambiente di produzione con un valore non corrispondente ApplicationId , è possibile scrivere una query per aggiornare questi valori non corretti ApplicationId all'oggetto usato nell'ambiente ApplicationId di produzione. Dopo l'aggiornamento, gli utenti i cui account sono stati creati nell'ambiente di sviluppo potranno accedere all'applicazione Web nell'ambiente di produzione.

La buona notizia è che è possibile eseguire un semplice passaggio per assicurarsi che i due ambienti usino lo stesso ApplicationId , impostando in modo esplicito l'attributo applicationName in Web.config per tutti i provider di servizi dell'applicazione. L'attributo applicationName viene impostato in modo esplicito su "BookReviews" negli <membership> elementi e <roleManager> come illustrato in Web.config questo frammento di codice.

<membership defaultProvider="ReviewMembership">
    <providers>
        <clear />

        <add type="System.Web.Security.SqlMembershipProvider" 
             name="ReviewMembership" 
             connectionStringName="ReviewsConnectionString" 
             applicationName="BookReviews" />
    </providers>
</membership>

Per altre informazioni sull'impostazione dell'attributo applicationName e sulla logica sottostante, fare riferimento al post di blog di Scott Guthrie , impostare sempre la proprietà applicationName durante la configurazione di ASP.NET Membership e altri provider.

Gestione degli account utente nell'ambiente di produzione

Lo strumento di amministrazione del sito Web (WSAT) ASP.NET semplifica la creazione e la gestione degli account utente, la definizione e l'applicazione dei ruoli e la definizione delle regole di autorizzazione basate su utenti e ruoli. È possibile avviare WSAT da Visual Studio passando alla Esplora soluzioni e facendo clic sull'icona di configurazione ASP.NET oppure passando ai menu Sito Web o Progetto e selezionando la voce di menu Configurazione ASP.NET. Sfortunatamente, WSAT può funzionare solo con i siti Web locali. Di conseguenza, non è possibile usare WSAT dalla workstation per gestire il sito Web nell'ambiente di produzione.

La buona notizia è che tutte le funzionalità esposte da WSAT sono disponibili a livello di codice tramite le API appartenenza e ruoli; inoltre, molte delle schermate WSAT usano i controlli standard ASP.NET correlati all'accesso. In breve, è possibile aggiungere pagine ASP.NET al sito Web che offrono le funzionalità di gestione necessarie.

Tenere presente che un'esercitazione precedente ha aggiornato l'applicazione Web Book Reviews per includere una ~/Admin cartella e questa cartella è stata configurata per consentire solo agli utenti nel ruolo di Amministrazione. È stata aggiunta una pagina a tale cartella denominata CreateAccount.aspx da cui un amministratore può creare un nuovo account utente. Questa pagina usa il controllo CreateUserWizard per visualizzare l'interfaccia utente e la logica back-end per la creazione di un nuovo account utente. Inoltre, ho personalizzato il controllo per includere un controllo CheckBox che richiede se il nuovo utente deve essere aggiunto anche al ruolo di Amministrazione (vedere la figura 5). Con un po' di lavoro è possibile creare un set personalizzato di pagine che implementa le attività correlate alla gestione di utenti e ruoli che altrimenti verrebbero fornite da WSAT.

Nota

Per altre informazioni sull'uso delle API appartenenza e ruoli insieme ai controlli Web correlati all'accesso ASP.NET, leggere le esercitazioni sulla sicurezza dei siti Web personali. Per altre informazioni sulla personalizzazione del controllo CreateUserWizard, vedere l'articolo Creazione di account utente e archiviazione di informazioni utente aggiuntive oppure vedere l'articolo Erich Peterson , Personalizzazione del controllo CreateUserWizard.

Gli amministratori possono creare nuovi account utente

Figura 5: Gli amministratori possono creare nuovi account utente (fare clic per visualizzare l'immagine a dimensione intera)

Se è necessaria la funzionalità completa di WSAT, vedere Roll Your Own Web Site Administration Tool, in cui l'autore Dan Clem illustra il processo di creazione di uno strumento personalizzato simile a WSAT. Dan condivide il codice sorgente dell'applicazione (in C#) e fornisce istruzioni dettagliate per aggiungerlo al sito Web ospitato.

Riepilogo

Quando si distribuisce un'applicazione Web che usa l'implementazione del database dei servizi applicazioni, è prima necessario assicurarsi che il database di produzione disponga degli oggetti di database necessari. Questi oggetti possono essere aggiunti usando le tecniche descritte nell'esercitazione Distribuzione di un database ; in alternativa, è possibile usare lo aspnet_regsql.exe strumento , come illustrato in questa esercitazione. Altre sfide affrontate sono incentrate sulla sincronizzazione del nome dell'applicazione usato negli ambienti di sviluppo e produzione (che è importante se si vuole che gli utenti e i ruoli creati nell'ambiente di sviluppo siano validi nell'ambiente di produzione) e tecniche per la gestione degli utenti e dei ruoli nell'ambiente di produzione.

Buon programmatori!

Altre informazioni

Per altre informazioni sugli argomenti descritti in questa esercitazione, vedere le risorse seguenti: