Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Leggi il Capitolo 10 di esempio

10. WCF: Sicurezza, gestione e integrazione con Windows WF

WCF consente di curare la sicurezza dei dati inviati in rete, la gestione dei servizi ed è integrabile con Windows Workflow Foundation.

Nota – Gli argomenti trattati in questo capitolo si applicano anche a Visual Studio Express (è necessario Visual Web Developer 2008 Express per .NET Framework 3.5), con l’eccezione dell’ultima sezione. Inoltre, per realizzare gli obiettivi proposti è necessario avere installato Internet Information Services.

Considerazioni sulla sicurezza

Windows Communication Foundation è una tecnologia dalla potenza straordinaria per lo scambio di informazioni in rete. Tuttavia, proprio perché la rete, sia essa Intranet o Internet, è il mezzo di trasporto delle informazioni, ogni sviluppatore deve tenere nella giusta considerazione le problematiche inerenti la sicurezza. Pensate, per esempio, a quei siti che consentono l’acquisto on-line mediante autenticazione personale e inserimento del numero di carta di credito. Se la ricezione delle informazioni avviene mediante un servizio WCF, è necessario che questo sia estremamente sicuro, poiché può essere facilmente soggetto ad attacchi esterni volti a carpire le informazioni personali dei clienti. In sostanza, la sicurezza in WCF si interpone tra il servizio e il client, garantendo l’univocità e la certezza dell’identità di ciascuno dei due. Affrontare nel dettaglio una tematica di questo tipo è di certo interessante, ma richiederebbe decine di pagine, esulando dallo scopo introduttivo di questo manuale. Pertanto, in questa sezione daremo le informazioni di base sulla sicurezza in WCF, facendo degli esempi pratici. Gli ulteriori approfondimenti sulla materia possono poi essere sviluppati tramite la pagina principale della documentazione MSDN, che riguarda la sicurezza in WCF e che può essere visitata al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms732362.aspx

La sicurezza, in WCF, si suddivide in tre fasi principali: il trasferimento dei dati, l’autenticazione e l’auditing. Iniziamo ora a vedere come WCF implementi dei modelli di sicurezza estremamente versatili.

Modalità di trasferimento dei dati

Sorgente di esempio: Capitolo 10\DelSole.WCFAuthenticationService

La sicurezza relativa al trasferimento dei dati è definita Transfer Security e si occupa di garantire l’integrità dei dati trasferiti e l’identità sia del servizio che del client. Sostanzialmente, la Transfer Security si suddivide in due parti: una destinata alla sicurezza del protocollo di trasporto (TransportMode); l’altra alla sicurezza dei messaggi (MessageMode). La prima, che si preferisce nelle Intranet aziendali, garantisce la crittografia dei dati mediante certificati SSL, protocolli HTTPS o autenticazione di tipo username/password. Sebbene molto valida e di relativamente rapida implementazione, questa tecnica è piuttosto lenta. Inoltre, è consigliabile solo se il passaggio dei dati avviene tra un client e un singolo server, mentre, se il passaggio deve avvenire tra un client e più server, la sicurezza è garantita solo nel passaggio al primo server della serie. Per questo motivo, spesso è conveniente utilizzare la tecnica destinata ai messaggi, ossia MessageMode, che è quella che utilizzeremo anche noi nel nostro progetto dimostrativo che illustreremo a breve. Con questa tecnica, sono i messaggi stessi, generati da WCF, a crittarsi autonomamente, senza ricorrere alla sicurezza del protocollo di trasporto. Prima di passare al codice sorgente, facciamo un’importante considerazione. Sia i TransportMode che i MessageMode vengono stabiliti mediante i binding, di cui abbiamo parlato all’inizio del Capitolo 9 (per gli approfondimenti rimandiamo alla documentazione). Se prendiamo in considerazione il nostro primo servizio WCF (realizzato sempre nel capitolo precedente), chiamato DelSole.WCFService, nel file Web.config abbiamo indicato le seguenti righe di codice XML:

<service

    name="DelSole.WCFService.Services">

  <endpoint address=""

            binding="basicHttpBinding"

            contract="DelSole.WCFService.IMyService" />

</service>

Con queste poche righe, abbiamo comunicato al servizio di usare un protocollo di trasporto HTTP senza alcuna autenticazione, pertanto totalmente insicuro, sebbene di facile raggiungimento per tutti i client che ne facciano richiesta. Si potrebbe modificare il file Web.config scrivendo il seguente codice XML:

<services>

  <service name="DelSole.WCFService.Services">

    <endpoint address=" " binding="wsHttpBinding"

    bindingConfiguration="TrasportoAnonimo"contract="DelSole.WCFService.IMyService" />

  </service>

</services>

<bindings>

  <wsHttpBinding>

    <binding name="TrasportoAnonimo">

      <security mode="Transport">

        <transport clientCredentialType="None"/>

      </security>

    </binding>

  </wsHttpBinding>

</bindings>

Con questo codice, stiamo comunicando al servizio che i dati devono essere trasportati (security mode=”Transport”) utilizzando il protocollo HTTPS (elemento wsHttpBinding) e che non è richiesta al client alcuna autenticazione (clientCredentialType=”None”). Si tratta di uno scenario comune, che però può essere migliorato. Il seguente frammento di codice XML mostra, invece, come stabilire l’utilizzo di un certificato digitale per rendere sicura la trasmissione dei dati:

<services>

  <service name="DelSole.WCFService.Services" behaviorConfiguration="ConCertificato">

    <endpoint address=" " binding="wsHttpBinding"

        bindingConfiguration="TrasportoAnonimo"contract="DelSole.WCFService.IMyService" />

  </service>

</services>

<bindings>

  <wsHttpBinding>

    <binding name="Certificate">

      <security mode="Message">

        <transport clientCredentialType="Certificate"/>

      </security>

    </binding>

  </wsHttpBinding>

</bindings>

<behaviors>

  <behavior name="ConCertificato">

    <serviceCredentials>

      <clientCertificate trustedStoreLocation="LocalMachine" />

      <serviceCertificate storeLocation="LocalMachine"

          storeName="My" findValue="IlMioCertificato" x509FindType="FindBySubjectDistinguishedName" />

    </serviceCredentials>

  </behavior>

</behaviors>

Il certificato viene ricercato a livello di macchina (e non dell’utente che ha eseguito l’accesso al sistema), nel deposito di sistema dei certificati. Ovviamente, bisogna poi far sì che il client utilizzi lo stesso certificato per connettersi al servizio. Lo si può fare modificando il file App.config del client come segue:

<services>

  <service name=" DelSole.WCFService.Services " behaviorConfiguration="ConCertificato">

    <endpoint address=" " binding="wsHttpBinding"

        bindingConfiguration="TrasportoAnonimo"contract="DelSole.WCFService.IMyService" />

  </service>

</services>

<bindings>

  <wsHttpBinding>

    <binding name="Certificate">

      <security mode="Message">

        <transport clientCredentialType="Certificate"/>

      </security>

    </binding>

  </wsHttpBinding>

</bindings>

<behaviors>

  <behavior name="ConCertificato">

    <clientCredentials>

      <clientCertificate storeLocation="CurrentUser"

storeName="My" x509FindType="FindBySubjectName" findValue="client.com"/>

      <serviceCertificate storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" findValue="cn=IlMioCertificato" />

    </clientCredentials>

  </behavior>

</behaviors>

Tra l’altro, questi frammenti di codice introducono l’utilizzo del metodo MessageMode per il trasporto dei dati. A questo proposito, potremmo sfruttare la crittazione dei messaggi prevista da WCF, unita all’autenticazione dell’utente, per migliorare il nostro servizio. Pertanto, se non lo avete ancora fatto, riprendete il progetto chiamato DelSole.WCFService, creato all’inizio del Capitolo 9, e rinominate il solo file di soluzione in DelSole.WCFAuthenticationService. Fatto questo, aprite il file Web.config e modificatelo come segue:

<?xml version="1.0" encoding="utf-8" ?>

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

  <system.serviceModel>

    <services>

      <service

          name="DelSole.WCFService.Services"

          behaviorConfiguration="DelSoleWCFServiceBehavior">

        <endpoint address=""

                  binding="wsHttpBinding"

                  contract="DelSole.WCFService.IMyService"

                  bindingConfiguration="MessageSecurity" />

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name="DelSoleWCFServiceBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="False" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <bindings>

      <wsHttpBinding>

        <binding name="MessageSecurity">

          <security mode="Message">

            <transport clientCredentialType="Windows"/>

          </security>

        </binding>

      </wsHttpBinding>

    </bindings>

  </system.serviceModel>

</configuration>

Abbiamo modificato l’elemento Endpoint, specificando l’utilizzo del binding wsHttpBinding, decisamente più sicuro. La configurazione del binding è definita in un elemento Bindings, che contiene, a sua volta, un elemento wsHttpBinding il quale, oltre a definire un identificatore (Name), stabilisce che si utilizza la modalità di sicurezza prevista per i messaggi (Security Mode=”Message”) e che per il trasporto dei dati è richiesta l’autenticazione Windows. WCF prevede diversi tipi di autenticazione, tra cui: quella tramite certificati (di grande importanza), anonima o Windows. Quest’ultima ci permetterà di specificare le credenziali a livello utente di Windows ed è sufficiente per i nostri scopi didattici. Notate bene che tutto ciò che è relativo ai binding, alla sicurezza e alle credenziali può essere scritto anche tramite codice Visual Basic e Visual C#. Tuttavia, modificando il file Web.config, abbiamo reso estremamente semplice la ripubblicazione del servizio. Si rende ora necessario fare alcune piccole modifiche all’applicazione client. Sempre in riferimento al nostro esempio, attivate prima il progetto ClientApplication, appartenente alla soluzione DelSole.WCFAuthenticationService. In secondo luogo, passate al file di code-behind, relativo al file Window1.xaml (quindi Window1.xaml.vb o Window1.xaml.cs). Posizionatevi sul metodo Window1_Loaded e modificate il codice come segue:

Visual Basic:

    Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        'Modificare nome utente e password con le proprie credenziali

        client.ClientCredentials.UserName.UserName = "Alessandro"

        client.ClientCredentials.UserName.Password = ""

        client.Open()

        TextBoxMoltiplicazione.Text = client.Moltiplicazione(2, 4).ToString

    End Sub

Visual C#:

        private void Window1_Loaded(object sender, RoutedEventArgs e)

        {

            //Modificare nome utente e password con le proprie credenziali

            client.ClientCredentials.UserName.UserName = "Alessandro";

            client.ClientCredentials.UserName.Password = "";

            client.Open();

            TextBoxMoltiplicazione.Text = client.Moltiplicazione(2, 4).ToString();

        }

Così facendo, il nostro client fornirà le proprie credenziali a livello di utente Windows al servizio, di modo che vi possa accedere dopo essere stato autenticato. Esistono diversi tipi di binding in WCF, relativi alla sicurezza. Ricordiamo, come esempio, i vari wsDualHttpBinding, NetTcpBinding e NetMsqmBinding, che permettono di stabilire le modalità di trasporto dei dati e il relativo livello di sicurezza.

Accesso al servizio basato sui ruoli

Coloro che hanno avuto modo di approfondire il funzionamento del Code Access Security del .NET Framework, sanno che esistono due importanti namespace: System.Security.Permissions e System.Security.Principals. Questi namespace implementano classi che gestiscono l’accesso alle risorse desiderate basandosi sui cosiddetti ruoli. I ruoli definiscono i gruppi di utenti che hanno diritto all’accesso a determinate risorse. Per esempio, il gruppo Administrators fa parte del ruolo degli amministratori di sistema, pertanto con pieno accesso alle risorse. È possibile applicare questi concetti anche ai servizi scritti per Windows Communication Foundation, in modo da consentire l’accesso ai servizi stessi solo alle persone che appartengono a un determinato ruolo del sistema. Osservate come venga riscritto il metodo Moltiplicazione implementato nel nostro servizio:

Visual Basic:

<PrincipalPermission(SecurityAction.Demand), Role:="Builtin\Administrators"> Public Function Moltiplicazione(ByVal primoValore As Integer, ByVal secondoValore As Integer) As Integer Implements IMyService.Moltiplicazione

        Return (primoValore * secondoValore)

End Function

Visual C#:

        [PrincipalPermission(SecurityAction.Demand, Role = "Builtin\\Adminstrator")]

        public int Moltiplicazione(int primoValore, int secondoValore)

        {

            return (primoValore * secondoValore);

        }

Utilizzando questa tecnica, solo gli amministratori di sistema potranno avere accesso al metodo Moltiplicazione. Imparando a padroneggiare questa metodologia, sarete in grado di consentire l’accesso a più utenti appartenenti a ruoli diversi.

Servizi di auditing

WCF implementa una funzionalità molto utile di tracciamento, chiamata auditing. I servizi di auditing consentono di monitorare tutto ciò che accade al servizio, memorizzando nel registro degli eventi di Windows, sotto forma di log, gli eventi occorsi. Per esempio, i servizi di auditing consentono di memorizzare tutti i tentativi di accesso al servizio (compresi quelli non autorizzati), errori e tentativi di manomissione. L’auditing avviene principalmente a livello di autenticazione dell’utente e di crittografia dei messaggi. Si tratta di un servizio che offre molte funzionalità, anche complesse. In questo paragrafo, vedremo un semplice esempio di servizio di auditing, che consente di memorizzare nel registro degli eventi di Windows (sezione Application) l’esito positivo o negativo degli accessi al servizio da parte del client. Tutto ciò viene fatto, ancora una volta, tramite il file Web.config, sebbene sia possibile anche da codice managed. La scelta di operare sul file di configurazione consente, come già visto in altre occasioni, di rendere più semplice la distribuzione del servizio senza doverlo ricompilare. Sempre facendo riferimento alla soluzione di esempio, chiamata DelSole.WCFAuthenticationService, vi sarà sufficiente modificare la sezione relativa al behavior definito precedentemente, così come segue:

<behavior name="DelSoleWCFServiceBehavior">

  <serviceMetadata httpGetEnabled="true" />

  <serviceDebug includeExceptionDetailInFaults="False" />

  <serviceSecurityAudit auditLogLocation="Application"

          serviceAuthorizationAuditLevel="SuccessOrFailure"/>

</behavior>

Abbiamo aggiunto, in sostanza, un elemento chiamato serviceSecurityAudit, che stabilisce che le informazioni vanno tracciate nel registro dei log di Windows alla sezione Application (attributo auditLogLocation) e che bisogna monitorare gli accessi all’applicazione (attributo serviceAuthorizationAuditLevel), memorizzando il successo o l’insuccesso degli accessi stessi (valore SuccessOrFailure). Se modifichiamo la riga in questo modo:

<serviceSecurityAudit auditLogLocation="Application"

            serviceAuthorizationAuditLevel="SuccessOrFailure" messageAuthenticationAuditLevel="SuccessOrFailure" />

permettiamo anche il tracing della verifica della crittografia dei messaggi (esito positivo o negativo). Può accadere, comunque, che durante l’auditing vengano riscontrati dei problemi di vario tipo. Si può utilizzare un attributo SuppressAuditFailure impostato su True per evitare che vengano sollevate eccezioni. Se invece si suppone di prevedere l’intercettazione di eccezioni specifiche per l’auditing, questo attributo può essere impostato su False. Il seguente frammento di codice, modifica il precedente ed evita che vengano sollevate eccezioni dovute a problemi di auditing:

<serviceSecurityAudit auditLogLocation="Application"

            serviceAuthorizationAuditLevel="SuccessOrFailure" messageAuthenticationAuditLevel="SuccessOrFailure" suppressAuditFailure = "True"/>

Questi sono solo piccoli esempi di utilizzo degli auditing, che sono piuttosto complessi ma che consentono, al tempo stesso, di tenere traccia di qualsiasi cosa accada al servizio WCF implementato. La documentazione MSDN è molto esaustiva al riguardo e informazioni di dettaglio possono essere reperite al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms731669.aspx

Gestione dei servizi

Windows Communication Foundation mette a disposizione diversi strumenti per una migliore gestione dei servizi, sia a livello di configurazione per il servizio e per i client, che a livello di diagnostica. In particolare, esistono due strumenti molto utili, chiamati Service Configuration Editor e Service Trace Viewer, entrambi disponibili tra i tool di Windows SDK per Visual Studio. Si tratta di comodi strumenti a interfaccia grafica che, tramite finestre e pochi clic di mouse, consentono di intervenire sia sulla configurazione sia sui log prodotti dalle connessioni al servizio. Iniziamo a vedere come rendere più produttiva la gestione della configurazione dei servizi fino ad arrivare a implementare funzionalità di diagnostica.

Service Configuration Editor

Nel corso del Capitolo 9 e di questo capitolo, abbiamo realizzato alcuni servizi basati su WCF e alcune applicazioni client in grado di connettersi a questi servizi. Durante la realizzazione degli esempi, abbiamo visto come, tramite i file di configurazione Web.config e App.config, sia possibile stabilire il comportamento dei servizi e dei client scrivendo codice XML. Trattandosi di esempi piuttosto semplici, utili per fini didattici, i file di configurazione sono stati definiti scrivendo codice altrettanto semplice, al cui interno insiste un numero limitato di nodi ed elementi XML, perché limitato è il numero di funzionalità di WCF che abbiamo sfruttato. In scenari reali, soprattutto in applicazioni destinate all’utilizzo aziendale, è possibile che sia necessario specificare un gran numero di opzioni relative al funzionamento del servizio (pensate, per esempio, ai Binding e ai Behavior). In questi casi, scrivere manualmente tutto il codice XML necessario al servizio diventa piuttosto dispendioso. Inoltre, un ipotetico amministratore di sistema potrebbe conoscere gli elementi alla base di WCF, ma non sapere come tradurli sotto forma di codice XML. Fortunatamente, Windows SDK include un fantastico strumento, chiamato Service Configuration Editor, che può essere lanciato tramite l’apposito collegamento nella cartella Programmi|Microsoft Windows SDK|Tools del menu Start di Windows. Se avete installato Visual Studio 2008, il collegamento si trova nella cartella Programmi|Microsoft Windows SDK v6.0A|Tools. Service Configuration Editor, che d’ora in avanti definiremo SCE per brevità, permette di creare da zero file di configurazione, oppure di elaborarne di esistenti. Inoltre, consente di creare tutto il necessario per l’implementazione delle proprietà relative a servizi e client (per esempio, Contract, Binding e Behavior) tramite un’interfaccia grafica molto intuitiva.

Nota – La versione di Service Configuration Editor distribuita con Visual Studio 2008 è più recente rispetto a quella distribuita con Windows SDK. Se utilizzate le edizioni Express, questo strumento viene installato solo con Visual Web Developer 2008 Express.

In questa sede non è possibile descrivere tutte le funzionalità di SCE, però vedremo come utilizzarlo per esplorare file di configurazione esistenti, dando cenno delle modalità da seguire per aggiungere funzionalità e, in particolare, addentrandoci nell’utilizzo dello strumento per aggiungere al servizio funzionalità di diagnostica. Una volta avviato, dal menu File, selezionate il comando Open|Config file. Dalla finestra di dialogo, selezionate il file Web.config, relativo al servizio DelSole.WCFService (l’esempio che abbiamo creato nel Capitolo 9), che prendiamo qui in considerazione per la sua semplicità. Fatto questo, la finestra di SCE si presenta come nella Figura 10.1.

Figura 10.1 – L’esplorazione del file Web.config con Service Configuration Editor.

Come potete osservare, nell’area di lavoro vengono fornite informazioni generali sul servizio, come l’ABC. Sulla sinistra, invece, è presente una struttura ad albero che vi consente di sfogliare la struttura del file di configurazione, a seconda del particolare aspetto del servizio (per esempio, Binding e Behavior). Vi sarà sufficiente fare clic sui vari elementi della struttura ad albero, per conoscere tutte le informazioni relative al servizio già implementate. Per aggiungerne di nuove, come per esempio una nuova configurazione per i Binding, potete utilizzare gli appositi comandi messi a disposizione dal nostro tool. Inoltre, potete modificare i valori esistenti sempre spostandovi tra i vari elementi della struttura. Service Configuration Editor può essere anche avviato dal menu Strumenti di Visual Studio, oppure facendo clic destro sul file di configurazione desiderato nella finestra Esplora soluzioni, sempre all’interno dell’IDE. Un’ultima precisazione circa l’elaborazione dei file di configurazione. Dovrete elaborare il file Web.config del servizio se quest’ultimo è stato pubblicato su un sito Web, mentre elaborerete il file App.config se il servizio è ospitato all’interno dell’applicazione client. Nel nostro caso abbiamo selezionato il Web.config perché, come ricorderete, il servizio è stato pubblicato su un sito web locale tramite Internet Information Services. Come anticipato in precedenza, descrivere ogni aspetto o funzionalità di SCE non è possibile in questa sede. A questo proposito, potete consultare la libreria MSDN al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms732009.aspx

Ci occupiamo, invece, di vedere come utilizzare SCE, per modificare il file di configurazione del servizio, al fine di implementare funzionalità di diagnostica. In questo modo, potrete anche prendere confidenza con lo strumento per i vostri successivi utilizzi.

Implementare funzionalità di diagnostica

WCF fornisce numerose funzionalità di diagnostica per i servizi e per i client. Queste funzionalità consentono di memorizzare, sotto forma di file di log, tutto ciò che accade al servizio e al client durante tutto il ciclo di vita della loro comunicazione. A differenza di quanto abbiamo visto precedentemente per i servizi di auditing, che consentono di memorizzare una serie di informazioni nel registro di Windows, le funzionalità di diagnostica sono più articolate e consentono di essere suddivise in questo modo:

· Performance counter, che consentono di monitorare l’andamento delle prestazioni di servizio e client;

· Windows Management Instrumentation, che permettono di memorizzare i dati in modo tale da poter essere elaborati tramite la omonima console di sistema;

· Message logging, che consentono di analizzare ciò che accade a livello di scambio di messaggi tra applicazioni;

· Tracing, che permettono di analizzare ed elaborare ogni singolo avvenimento che si verifica tra servizio e client durante tutto il ciclo di vita della comunicazione.

I servizi di diagnostica possono essere abilitati, nel file di configurazione, scrivendo alcune righe di codice XML. Nel caso si voglia eseguire un semplice monitoraggio, il codice XML è relativamente breve e semplice. Il seguente code snippet XML, mostra come aggiungere un nodo System.Diagnostics al file di configurazione:

<system.diagnostics>

  <sources>

    <source name="System.ServiceModel"

            switchValue="Information, ActivityTracing"

            propagateActivity="true">

      <listeners>

        <add name="traceListener"

            type="System.Diagnostics.XmlWriterTraceListener"

            initializeData= "c:\Diagnostica\DiagnosticaServizio.svclog" />

      </listeners>

    </source>

  </sources>

</system.diagnostics>

Come potete osservare, sebbene sia piuttosto breve, il codice non brilla per semplicità, anche perché le opzioni di diagnostica che è possibile impostare sono molte e articolate. Capite bene, allora, come l’ausilio di uno strumento a interfaccia grafica come SCE diventi di fondamentale importanza. Ci proponiamo di aggiungere funzionalità di diagnostica al nostro servizio. Nella struttura ad albero a sinistra, fate clic su Diagnostics. Nell’area di lavoro apparirà l’elenco delle funzionalità di diagnostica che è possibile attivare. Fate clic su Enable tracing, al fine di monitorare tutto ciò che accade al servizio. Quindi, fate clic su Enable Autoflush, affinché, alla chiusura dell’applicazione, i risultati vengano memorizzati in un file di log. Fate clic sulla voce Trace level, relativa alla funzionalità Tracing. Apparirà una finestra chiamata Tracing Settings (Figura 10.2) che consente di impostare, tra l’altro, il livello di errore o evento da scrivere nel log.

Figura 10.2 – La finestra Tracing Settings per la diagnostica.

Nella casella combinata, selezionate la voce Verbose, che scriverà una descrizione dettagliata degli accadimenti nel file di log. Successivamente, fate clic sulla voce ServiceModelTraceListener e, nella finestra che appare, selezionate tutte le voci disponibili, in modo da avere il più ampio ventaglio di aspetti da monitorare. Fatto questo, le impostazioni di diagnostica si presentano come nella Figura 10.3.

Figura 10.3 – Le impostazioni definitive per la diagnostica del servizio.

Salvate i cambiamenti al file di configurazione, utilizzando il comando Save del menu File. SCE prestabilisce il percorso e il nome per il file di log, ma è possibile specificarne uno personalizzato. A questo punto, vediamo il risultato pratico di queste operazioni. Avviate l’applicazione client ClientApplication, quindi chiudetela. Secondo le impostazioni definite in precedenza, il file di log viene scritto alla chiusura dell’applicazione. Pertanto, la fase successiva è quella dell’analisi del file di log stesso. Lo facciamo utilizzando lo strumento Service Trace Viewer.

Service Trace Viewer

Service Trace Viewer è uno strumento a interfaccia grafica, appartenente ai tool di Windows SDK per Visual Studio, che consente di visualizzare e analizzare il contenuto dei file di log prodotti dalle funzionalità di diagnostica di WCF. Potete avviarlo utilizzando l’omonimo collegamento, disponibile nella cartella Programmi|Microsoft Windows SDK|Tools del menu Start. Anche in questo caso, se utilizzate Visual Studio 2008, il collegamento si trova nella cartella Programmi|Microsoft Windows SDK v6.0A|Tools.

Nota – La versione di Service Trace Viewer distribuita con Visual Studio 2008 è più recente rispetto a quella distribuita con Windows SDK. Se utilizzate le edizioni Express, questo strumento viene installato solo con Visual Web Developer 2008 Express.

Una volta avviato, dal menu File selezionate il comando Open. Nella finestra di dialogo che appare, andate a cercare e poi selezionate il file Web_tracelog.svclog, creato dai servizi di diagnostica, che, qualora non venisse specificato diversamente, viene generato nella cartella contenente il progetto di Visual Studio. Fatto questo, l’applicazione viene suddivisa in due aree: sulla sinistra, potete notare l’elenco delle attività descritte nel log; l’area posta a destra mostrerà i dettagli delle attività selezionate. Per esempio, fate clic sull’attività che inizia con Elaborazione azione, a sinistra. Questa azione si riferisce alla richiesta formulata dal client per utilizzare il metodo Moltiplicazione. Come potete osservare, nell’area a destra, viene mostrata la sequenza di avvenimenti riferibili a quella particolare attività. Nell’area sottostante, vengono mostrati ulteriori dettagli per ciascuna voce elencata (Figura 10.4).

Figura 10.4 – L’analisi del log del servizio tramite Service Trace Viewer.

È anche possibile visualizzare la rappresentazione XML di ciascuna elaborazione, mediante la scheda XML relativa ai dettagli degli eventi. A questo punto, fate clic sulla scheda denominata Graph, posta nell’area sinistra. Come potete vedere, viene mostrata una rappresentazione grafica di tutta la sequenza degli eventi, con tanto di data e ora. Il grafico è navigabile e, ogni qual volta si fa clic su uno degli elementi, l’area destra relativa alle descrizioni viene automaticamente aggiornata, in modo da mostrare i dettagli dell’evento selezionato (Figura 10.5).

Figura 10.5 – La rappresentazione grafica del log del servizio.

Service Trace Viewer è un’utilità molto articolata, che consente analisi molto particolareggiate sui log prodotti dalle applicazioni. Per ottenere informazioni più dettagliate sul significato delle varie rappresentazioni degli eventi recuperati dal log, potete consultare la documentazione ufficiale Microsoft relativa al tool in esame, al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms732023.aspx

In questa pagina della documentazione, vengono anche elencate le icone mostrate dal programma e associate ai vari eventi, in particolare quelli che rappresentano gli errori verificatisi.

Integrare WCF e WF

Una caratteristica molto interessante della programmazione basata su .NET Framework 3.0 è quella che consente l’integrazione tra due tecnologie tra loro complementari: Windows Communication Foundation e Windows Workflow Foundation. La prima tecnologia, infatti, consente di esporre al mondo esterno, tramite servizi, funzionalità che possono essere utilizzate all’interno dei flussi di lavoro creati con la seconda. In questa sezione, ricostruiremo il progetto IfElseActivityDemo, creato nel Capitolo 7, al quale faremo spesso riferimento, facendo in modo, però, che alcune funzionalità siano implementate in un servizio WCF e utilizzate dal workflow. Prima di proseguire nella lettura, si consiglia quindi di rileggere la sezione del Capitolo 7 dedicata ai flussi di lavoro sequenziali, con particolare riferimento all’attività IfElse e al progetto dimostrativo IfElseActivityDemo.

Logica di implementazione

Focalizziamo ora l’attenzione su cosa deve fare il workflow e, conseguentemente, su come implementare il servizio, prima di passare alla scrittura del codice vero e proprio. Nel progetto IfElseActivityDemo originario, viene richiesta l’immissione della propria età nella finestra della Console. Viene poi elaborata la condizione verificatasi, sulla base del valore costituente l’età, e mostrato un messaggio finale all’utente. Nel progetto originario tutte queste elaborazioni avvengono tramite codice appositamente scritto nel workflow. Potremmo, per esempio, creare un servizio WCF che implementi un metodo per la verifica dell’età (maggiore o minore di 18 anni) e dei metodi che restituiscano il messaggio da mostrare all’utente a seconda della condizione verificatasi. In questo modo, alleggeriremo il codice nel progetto WF, sfruttando l’integrazione con il servizio WCF. Ci occupiamo ora di realizzare dette procedure tramite codice.

Creazione del servizio WCF

Sorgente di esempio: Capitolo 10\DelSole.WorkflowService\ DelSole.WorkflowService

Avviate Visual Studio e, dal menu File, selezionate il comando Nuovo|Progetto. Siete ormai diventati molto abili nel gestire progetti WCF, pertanto selezionate il modello WCF Service Library nel linguaggio che preferite. Quando il progetto viene creato, rinominate, tramite la finestra Esplora soluzioni, il file Class1.vb/Class1.cs in Service.vb/Service.cs. Attivate l’editor di codice su quest’ultimo file ed eliminate completamente il suo contenuto, a eccezione delle direttive Imports (per Visual Basic) o using (per Visual C#). Definiamo, in primo luogo, il Contract del servizio tramite la seguente interfaccia:

Visual Basic:

<ServiceContract()> _

Public Interface IMyService

    <OperationContract()> _

    Function CalculateAge(ByVal age As Integer) As Boolean

    <OperationContract()> Function Maggiorenne() As String

    <OperationContract()> Function Minorenne() As String

End Interface

Visual C#:

    [ServiceContract()]

    public interface IMyService

    {

        [OperationContract]

        bool CalculateAge(int age);

        [OperationContract]

        string Maggiorenne();

        [OperationContract]

        string Minorenne();

    }

Si passa poi a dichiarare una classe che implementa l’interfaccia sopra descritta e che contiene il codice operativo dei metodi:

Visual Basic:

Public Class Services

    Implements IMyService

    Public Function CalculateAge(ByVal age As Integer) As Boolean Implements IMyService.CalculateAge

        If age >= 18 Then

            Return True

        Else

            Return False

        End If

    End Function

    Public Function Maggiorenne() As String Implements IMyService.Maggiorenne

        Return ("Sei maggiorenne: puoi guidare la macchina, ma con attenzione!")

    End Function

    Public Function Minorenne() As String Implements IMyService.Minorenne

        Return ("Sei minorenne: puoi guidare la bicicletta! :-)")

    End Function

End Class

Visual C#:

    public class Services : IMyService

    {

        public bool CalculateAge(int age)

        {

            if(age>=18) {

                return true;

            }

            else { return false; }

        }

        public string Maggiorenne()

        {

            return ("Sei maggiorenne: puoi guidare la macchina, ma con attenzione!");

        }

        public string Minorenne()

        {

            return ("Sei minorenne: puoi guidare la bicicletta! :-)");

        }

    }

Il metodo CalculateAge riceve un valore intero che rappresenta l’età che l’utente specificherà nell’esecuzione del workflow. A seconda che il valore sia maggiore-uguale o minore di 18 anni, il metodo restituisce True o False. Viene restituito proprio un valore booleano perché questo servirà per valutare la condizione nell’attività IfElse del workflow. I due metodi Maggiorenne e Minorenne, invece, restituiscono una semplice stringa. Non è superfluo precisare che sono stati implementati due metodi invece che due proprietà, perché queste non possono essere contrassegnate dall’attributo OperationContract. Una volta scritto il codice, dal menu Progetto, selezionate il comando Aggiungi nuovo elemento. Nella omonima finestra che appare, selezionate File di testo e assegnate al file il nome Service.svc, per l’aggiunta dei dati relativi al servizio. Fatto questo, digitate la seguente riga all’interno del file:

Visual Basic:

<%@ServiceHost Language="vb" Debug="true" Service="DelSole.WorkflowService.Services" %>

Visual C#:

<%@ServiceHost Language="c#" Debug="true" Service="DelSole.WorkflowService.Services" %>

L’ultimo passaggio per completare il servizio è quello di aggiungere un file di configurazione Web.config, del tutto analogo al progetto DelSole.WCFService visto all’inizio di Capitolo 9, contenente il seguente codice XML:

XML:

<?xml version="1.0"?>

<configuration>

  <system.serviceModel>

    <services>

      <service

          name="DelSole.WorkflowService.Services"

          behaviorConfiguration="DelSoleWorkflowServiceBehavior">

        <endpoint address=""

                  binding="basicHttpBinding"

                  contract="DelSole.WorkflowService.IMyService" />

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name="DelSoleWorkflowServiceBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="False" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Per i dettagli sul file di configurazione, potete consultare la sezione Creazione di un servizio WCF. Successivamente, compilate il progetto. Utilizzando le modalità descritte nel paragrafo Pubblicazione del servizio su IIS, pubblicate il servizio appena creato, assegnando l’identificatore DelSole_WorkflowService in Gestione Internet Information Services.

Creazione del Workflow

Sorgente di esempio: Capitolo 10\DelSole.WorkflowService\WCFIfElseActivityDemo

Dopo che il servizio è stato pubblicato su un server, è necessario aggiungere alla soluzione un progetto di applicazione client, che in questo caso sarà un flusso di lavoro basato su Windows Workflow Foundation. Dal menu File, selezionate il comando Aggiungi|Nuovo progetto. Nella finestra che appare, selezionate la cartella di progetti, denominata Workflow, e selezionate il modello Applicazione console flusso di lavoro sequenziale, assegnando al progetto il nome WCFIfElseActivityDemo. In primo luogo, aggiungete un riferimento all’assembly System.ServiceModel.dll, in modo da poter utilizzare le funzionalità di WCF. In secondo luogo, aggiungete un riferimento al servizio (comando Add service reference del menu Progetto), specificando rispettivamente, nella finestra che appare, l’URL http://localhost/DelSole_WorkflowService/service.svc?wdsl e l’identificatore DelSole.WorkflowService. Nella finestra Esplora soluzioni, fate doppio clic sul file Workflow1 per attivare il designer dei flussi. Ricostruite l’esatta sequenza di attività, che abbiamo descritto nel Capitolo 7, utilizzando i seguenti oggetti:

· un’attività Code, chiamata leggeEtà;

· un’attività IfElse, per la quale rinominerete l’oggetto IfElseBranch1 in seiMaggiorenne e IfElseBranch2 in seiMinorenne;

· un’attività Code, dipendente da seiMaggiorenne, chiamata Maggiorenne;

· un’attività Code, dipendente da seiMinorenne, chiamata Minorenne.

Il tutto deve apparire esattamente come nella Figura 10.6.

Figura 10.6 – La sequenza di attività implementata nel designer di WF.

La domanda che ora ci si deve porre è: dove va inserito il codice di connessione al servizio? La risposta è molto semplice: nell’evento ExecuteCode di ciascuna attività che si desidera. Dovrete sempre tenere a mente questo concetto fondamentale ogni qualvolta scriverete applicazioni che integrano WCF e WF. Passate all’editor di codice e scrivete quanto segue:

Visual Basic:

    Private age As Integer

    Private client As DelSole_WorkflowService.MyServiceClient

    Private Sub leggeEtà_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)

        client = New DelSole_WorkflowService.MyServiceClient

        client.Open()

        Console.WriteLine("Inserisci la tua età:")

        age = Convert.ToInt32(Console.ReadLine)

    End Sub

Visual C#:

        int age;

        DelSole_WorkflowService.MyServiceClient client;

        private void leggeEtà_ExecuteCode(object sender, EventArgs e)

        {

            client = new DelSole_WorkflowService.MyServiceClient();

            client.Open();

            Console.WriteLine("Inserisci la tua età:");

            age = Convert.ToInt32(Console.ReadLine());

        }

La prima attività Code che viene eseguita nel workflow istanzia il servizio e si connette a esso, per poi richiedere all’utente di immettere la propria età, in maniera del tutto analoga al progetto originario. Tornate, ora, al designer del flusso. È infatti necessario impostare la proprietà Condition dell’attività seiMaggiorenne. Potete farlo tramite la Finestra delle proprietà, dopo aver selezionato l’attività in questione, specificando il valore Condizione di codice per la proprietà Condition. Espandete quest’ultima proprietà e, nell’ulteriore campo Condition, digitate zero e premete Invio, al fine di attivare l’editor di codice nel quale digiterete quanto segue:

Visual Basic:

    Private Sub zero(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.ConditionalEventArgs)

        e.Result = client.CalculateAge(age)

    End Sub

Visual C#:

        private void zero(object sender, ConditionalEventArgs e)

        {

            e.Result = client.CalculateAge(age);

        }

Il metodo zero gestisce la valutazione della condizione vera o falsa. Nel progetto originario, questa valutazione veniva fatta tramite codice scritto in questo metodo. In questo caso, invece, richiediamo la valutazione dell’età al metodo CalculateAge implementato nel servizio WCF. A seconda del valore True o False restituito da CalculateAge, il workflow genera l’evento ExecuteCode per gli oggetti Maggiorenne e Minorenne, i quali si avvalgono, a loro volta, di altrettanti metodi definiti nel servizio per mostrare un messaggio all’utente, invece di implementare codice apposito al proprio interno. Il codice che completa il workflow è, quindi, il seguente:

Visual Basic:

    Private Sub Maggiorenne_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Console.WriteLine(client.Maggiorenne)

        Console.ReadLine()

        client.Close()

    End Sub

    Private Sub Minorenne_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Console.WriteLine(client.Minorenne)

        Console.ReadLine()

        client.Close()

    End Sub

Visual C#:

        private void Maggiorenne_ExecuteCode(object sender, EventArgs e)

        {

            Console.WriteLine(client.Maggiorenne());

            Console.ReadLine();

            client.Close();

        }

        private void Minorenne_ExecuteCode(object sender, EventArgs e)

        {

            Console.WriteLine(client.Minorenne());

            Console.ReadLine();

            client.Close();

        }

Premete F5 per avviare l’applicazione. Come potete osservare (Figura 10.7), il risultato è identico a quello prodotto dal progetto IfElseActivityDemo, con la differenza che questa volta abbiamo utilizzato metodi definiti in un servizio basato su Windows Communication Foundation, scoprendo le fantastiche possibilità di integrazione tra le due tecnologie. Come detto in precedenza, è importante tenere a mente che l’oggetto che riceve il servizio va istanziato nella proprietà ExecuteCode di un’attività (in questo caso la prima del flusso sequenziale).

Figura 10.7 – Il workflow in esecuzione, dopo la connessione al servizio.

Come spunto di studio personale, potete approfondire l’argomento relativo all’integrazione tra WCF e WF con riferimento all’esposizione di un workflow sotto forma di servizio WCF.

Novità in Visual Studio 2008

Visual Studio 2008 e .NET Framework 3.5 offrono nuovi strumenti per rendere più completa, e al tempo stesso più semplice, l’integrazione tra WCF e WF. Come accennato nel Capitolo 7, il .NET Framework 3.5 introduce due nuove attività per Windows Workflow Foundation, chiamate SendActivity e ReceiveActivity, specifiche per l’integrazione tra servizi WCF e flussi di WF. Come il nome lascia intendere, la prima consente l’invio di dati a un servizio, la seconda riceve dati da un servizio. Inoltre, Visual Studio 2008 introduce due nuovi modelli di progetto per WCF, chiamati Sequential Workflow Service Library e State Machine Service Library, che permettono di creare, rispettivamente, flussi di lavoro sequenziali e flussi di lavoro di tipo macchina a stati, esposti come servizi WCF e referenziabili da applicazioni client. Ovviamente, questi modelli sono disponibili per la sola creazione di progetti basati su .NET 3.5. Le operazioni da compiere rimangono sostanzialmente le stesse, ma l’IDE automatizza lo svolgimento di alcuni compiti (come l’aggiunta del file di configurazione e del file .svc).

Novità in .NET Framework 3.5

Come per le altre tecnologie, la nuova versione 3.5 del .NET Framework introduce alcune innovazioni in Windows Communication Foundation. Si tratta di novità che non influenzano gli argomenti trattati in questo manuale, ma che piuttosto estendono le funzionalità di questa tecnologia. Di seguito si riporta un elenco delle principali novità di WCF in .NET Framework 3.5:

· migliore gestione di servizi caratterizzati dalla necessità di rimanere in esecuzione per lungo tempo;

· migliore integrazione con Windows Workflow Foundation tramite l’introduzione di activity specifiche e una più semplice esposizione dei flussi di lavoro sotto forma di servizi WCF;

· introduzione di un modello di progetto per la creazione di servizi in grado di sottoscrivere feed RSS e Atom;

· utilizzo dei servizi WCF per creare applicazioni basate su Ajax, un modello di programmazione Web che consente lo scambio asincrono di dati tra browser e servizio referenziato dal client chiamante;

· supporto per servizi WCF distribuiti con ClickOnce secondo il livello di sicurezza di parziale attendibilità;

· supporto per la serializzazione dei tipi di dato JSON e POS;

· contatori delle prestazioni implementati di default.

Come potete osservare, gli argomenti sopra elencati costituiscono delle estensioni di Windows Communication Foundation, che non intaccano quanto descritto in questo manuale e che possono costituire ulteriori spunti di approfondimento da parte del lettore, anche tramite l’ausilio della documentazione a corredo di Visual Studio 2008 che, anche in questa occasione, costituisce un complemento di straordinaria portata.

Spunti di studio

Windows Communication Foundation è una tecnologia dalle potenzialità estremamente vaste. Lo scopo introduttivo di questo libro non permette di esaminare nel dettaglio tutte le funzionalità implementate Pertanto, si riportano di seguito una serie di argomenti di sicuro interesse per la programmazione avanzata in WCF, specificando i rispettivi riferimenti alla documentazione ufficiale Microsoft, sempre estremamente dettagliata. A questo proposito, l’indirizzo della pagina principale della libreria MSDN dedicata a WCF è il seguente:

http://msdn2.microsoft.com/en-us/library/ms735119.aspx

Transazioni

Con il termine transazione, in WCF, si intende il raggruppamento di più azioni in una singola unità di esecuzione. In questo modo, tutto ciò che influenza la transazione verrà applicato a tutte le operazioni che essa contiene. Le transazioni sono un argomento molto caratteristico di WCF e la documentazione MSDN relativa si trova al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms733904.aspx

Sessioni attendibili

Il concetto di sessione indica, in WCF, che servizio e client stanno comunicando mediante messaggi. Le sessioni attendibili (definite Reliable sessions in inglese) assicurano che i messaggi vengono consegnati una sola volta senza duplicati. Inoltre, in questo genere di sessioni lo scambio dei messaggi può avvenire secondo un determinato ordinamento e, qualora si verifichi una perdita di connessione, questa viene ripresa. Ulteriori informazioni sono reperibili al seguente URL:

http://msdn2.microsoft.com/en-us/library/ms733136.aspx

Estendere WCF

In WCF, è possibile modificare il comportamento di taluni componenti di runtime, al fine di consentire un controllo più particolareggiato dei servizi e dei client. Si tratta di un argomento piuttosto vasto, che viene suddiviso per tipologia di componente di runtime nella documentazione MSDN, reperibile al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms733848.aspx

Informazioni sulla privacy

La tutela della privacy delle applicazioni degli utenti è un aspetto assolutamente non trascurabile. Si tratta di una problematica tutelata dalle leggi internazionali e non deve essere sottovalutata. Poiché la programmazione con WCF si basa essenzialmente sullo scambio di dati in rete, può essere necessario trasferire dati che rientrano nella sfera della privacy dell’utente. A questo proposito, Microsoft ha realizzato delle linee guida per il rispetto della privacy nello sviluppo di applicazioni basate su WCF, che possono essere reperite al seguente indirizzo:

http://msdn2.microsoft.com/en-us/library/ms733927.aspx

Non è comunque superfluo ricordare che il D.Lgs. 196/2003 è il dettato normativo italiano al quale ci si deve conformare per quanto attiene la problematica in esame.

Si conclude così anche la breve panoramica su Windows Communication Foundation. Avete acquisito i concetti fondamentali per lavorare con questa tecnologia e avete a disposizione gli spunti principali di approfondimento, tenendo sempre a mente che i concetti fin qui descritti costituiscono una base iniziale e che abbiamo solo grattato la superficie di una tecnologia di incredibile potenza e versatilità.

Print | posted on lunedì 7 gennaio 2008 18:47 |

Powered by:
Powered By Subtext Powered By ASP.NET