[{"content":"Uno delle cose pi\u00f9 complesse da gestire nello sviluppo di qualsiasi applicazione, dalle semplici applicazioni client alle pi\u00f9 complesse soluzioni enterprise, riguarda la gestione della persistenza.\nIn ambiente .NET parte di questa complessit\u00e0 pu\u00f2 essere gestita attraverso l\u2019utilizzo delle migrazioni implementate internamente in Entity Framework.\nSpesso questa funzionalit\u00e0 \u00e8 vista come una utilit\u00e0 prettamente ad uso e consumo degli sviluppatori per aggiornare lo schema del database.\nQuando pensiamo di essere arrivati ad una situazione stabile eliminiamo tutte le migrazioni e partiamo da una situazione pulita.\nQuesta \u00e8 una frase che ho sentito davvero troppo spesso da molti colleghi, utilizzata in modo pi\u00f9 o meno consapevole, spesso i motivi che portano ad una esternalizzazione in tal senso \u00e8 una non sufficiente analisi del problema che genera molti cambiamenti, anche distruttivi, delle base dati.\nAltre volte pi\u00f9 consapevole e guidata dalla volont\u00e0 di non mantenere versioni precedenti a quella che supponiamo conterr\u00e0 dati &ldquo;reali&rdquo;, spesso questo coincide con il primo rilascio in produzione.\nIn realt\u00e0 quello che il tool ci offre \u00e8 un sistema di versionamento incrementale cosa che va ben oltre l&rsquo;ambito di competenza dello sviluppatore coinvolgendo anche DBA o pi\u00f9 propriamente DBRE, consiglio l&rsquo;ascolto dell&rsquo;episodio Da DBA a DBRE, il nuovo approccio DevOps nel mondo database, con Alessandro Alpi di dotNET{podcast} se volete approfondire le sottili differenze fra i due ruoli.\nCome posso effettuare operazioni sui dati? Questa cosa \u00e8 una di quelle operazioni che non \u00e8 possibile istruire in una migrazione attraverso le API che Entity Framework ci mette a disposizione in quanto \u00e8 molto dipendente dal dominio e cercare di formalizzare ci\u00f2 attraverso delle API sarebbe stato molto complesso se non impossibile ed \u00e8 per questi casi che \u00e8 stata prevista la scappatoia per l&rsquo;esecuzione di script SQL grezzi.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public partial class InitialWithSeed : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.Sql(@&#34;CREATE TABLE Persons ( Id int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) ); INSERT INTO Persons (Id, LastName, FirstName, Address, City) VALUES (1, &#39;Nesfield&#39;, &#39;Carmelia&#39;, &#39;802 Knutson Drive&#39;, &#39;Krajan Dua Putukrejo&#39;), (2, &#39;Valentino&#39;, &#39;Daune&#39;, &#39;1464 Forest Dale Road&#39;, &#39;Prozor&#39;), (3, &#39;Chrstine&#39;, &#39;Gus&#39;, &#39;817 Bonner Park&#39;, &#39;Lukunor&#39;), (4, &#39;Tebb&#39;, &#39;Stearne&#39;, &#39;63138 Colorado Plaza&#39;, &#39;Sanjiang&#39;), (5, &#39;Dyne&#39;, &#39;Gibby&#39;, &#39;39613 Pond Road&#39;, &#39;Th\u00e0nh Ph\u1ed1 H\u1ea1 Long&#39;), (6, &#39;MacShane&#39;, &#39;Sandra&#39;, &#39;02617 Continental Parkway&#39;, &#39;Cihambali&#39;), (7, &#39;Lissandri&#39;, &#39;Sidney&#39;, &#39;61 Talmadge Circle&#39;, &#39;Langar\u016bd&#39;), (8, &#39;O&#39;&#39; Quirk&#39;, &#39;Marc&#39;, &#39;828 Ohio Avenue&#39;, &#39;Farafangana&#39;), (9, &#39;Mabee&#39;, &#39;Man&#39;, &#39;79 Crownhardt Street&#39;, &#39;Kembang&#39;), (10, &#39;Izak&#39;, &#39;Bertie&#39;, &#39;7 High Crossing Junction&#39;, &#39;Taodian&#39;);&#34;); } } L&rsquo;esempio appena fatto potrebbe far storcere il naso ad entrambe le categorie.\nAgli sviluppatori perch\u00e9 sono presenti stringhe all&rsquo;interno del sorgente e al DBRE perch\u00e9 si troverebbe a lavorare &ldquo;scomodo&rdquo; senza completamento automatico.\nCome far felici i due mondi? Una caratteristica del tool \u00e8 quella di generare delle classi parziali che vengono abbinate a classi contente in file denominati {MigrationId}.Design.cs\n1 2 3 4 5 6 [DbContext(typeof(DesignContext))] [Migration(&#34;20220624071324_InitialWithSeed&#34;)] partial class InitialWithSeed { ... } che contengono l&rsquo;altra parte della classe parziale decorata con un attributo che ne identifica il contesto al quale \u00e8 legata ed uno che ne rappresenta l&rsquo;identificativo.\nPossiamo quindi pensare di estrarre lo script SQL all&rsquo;interno di un file con estensione .sql e sfruttare l&rsquo;identificativo della migrazione a runtime per leggerlo ed integrarlo all&rsquo;interno della migrazione.\nLa nostra migrazione avr\u00e0 quindi questo contenuto\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public partial class InitialWithSeed : Migration { protected override void Up(MigrationBuilder migrationBuilder) { var migrationAttribute = (MigrationAttribute)this.GetType() .GetCustomAttributes(typeof(MigrationAttribute), false) .Single(); migrationBuilder.Sql(File.ReadAllText(string.Format( CultureInfo.InvariantCulture, &#34;{1}{0}RawMigrations{0}{2}&#34;, Path.DirectorySeparatorChar, AppContext.BaseDirectory, $&#34;{migrationAttribute.Id}.sql&#34;))); } } e lo script SQL potr\u00e0 quindi essere letto dal percorso relativo alla directory di esecuzione \/RawMigrations\/20220624071324_InitialWithSeed.sql\nRicordiamoci inoltre di aggiungere l&rsquo;istruzione\n1 2 3 &lt;ItemGroup&gt; &lt;None Include=&#34;RawMigrations\\*.sql&#34; CopyToOutputDirectory=&#34;PreserveNewest&#34; \/&gt; &lt;\/ItemGroup&gt; all&rsquo;interno del .csproj per istruire MSBuild a pubblicare i file nella cartella di destinazione.\nCome sempre potete consultare il progetto dell&rsquo;intero esempio su\nbinick \/ samples ","permalink":"https:\/\/binick.blog\/it\/2022\/07\/02\/come-utilizzare-uno-script-sql-con-le-migrazioni-di-entity-framework\/","summary":"<p>Uno delle cose pi\u00f9 complesse da gestire nello sviluppo di qualsiasi applicazione, dalle semplici applicazioni client alle pi\u00f9 complesse soluzioni enterprise, riguarda la gestione della persistenza.<\/p>\n<p>In ambiente .NET parte di questa complessit\u00e0 pu\u00f2 essere gestita attraverso l\u2019utilizzo delle <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/managing-schemas\/migrations\/\">migrazioni<\/a> implementate internamente in Entity Framework.<\/p>\n<p>Spesso questa funzionalit\u00e0 \u00e8 vista come una utilit\u00e0 prettamente ad uso e consumo degli sviluppatori per aggiornare lo schema del database.<\/p>\n<blockquote>\n<p>Quando pensiamo di essere arrivati ad una situazione stabile eliminiamo tutte le migrazioni e partiamo da una situazione pulita.<\/p>","title":"Come utilizzare uno script SQL con le migrazioni di Entity Framework?"},{"content":"Molti di voi sapranno che ormai da un po\u2019 di tempo, 13 anni1 ormai, GitHub offre un servizio chiamato Pages che consente di ospitare siti statici, molto comodo per ospitare blog e documentazione.\nPer questo non \u00e8 una novit\u00e0 che questo blog, come molti altri, sia ospitato proprio li. Ed il motivo non \u00e8 perch\u00e9&rsquo; &ldquo;fa figo&rdquo; ma molto pi\u00f9 concreto e venale.\nUno degli obbiettivi che mi ero prefissato era quello di non farlo diventare una spesa viva, per questo scelsi l&rsquo;accoppiata HUGO + GitHub Pages, una scelta che oggi rifarei! Per una volta mi posso dare una pacca sulla spalla \ud83d\ude42.\nIn seguito, ho pensato che per avere una SEO migliore ed una maggiore associazione fra questo blog e me sarebbe stata buona cosa avere qualche dominio personalizzato.\nApplicare HTTPS. I domini li ho presi su ()register.it ed ho scelto di usare il servizio DNS di Cloudflare per cui dopo aver provveduto a configurare i record DNS in modo da supportare i domini personalizzati facendo puntare l&rsquo;apex e www al sottodominio github.io.\nA questo punto nonostante la sezione Pages delle impostazioni del repo riportasse il flag sulla correttezza dei record DNS impostati il messaggio subito sotto mi informava che il dominio non era correttamente configurato\nAnche la sezione Custom domain names that are unsupported confermata la validit\u00e0 della configurazione e questa cosa mi ha causato un gran mal di testa fino a quando non ho trovato questo post dal quale cito testualmente.\nIf you\u2019re configuring an apex domain make sure there are no other A, AAAA, or ALIAS records listed on the apex.\nIf you\u2019re configuring a subdomain, www or otherwise, make sure there are no other A, AAAA, or CNAME records on that same subdomain.\nUn po&rsquo; nello sconforto ho rimosso il record www ed a dispetto di quanto riportato dalla documentazione e della comparsa di questo warning\n(scusate ma mi sono dimenticato di catturare lo schermo \ud83d\ude4f per cui l&rsquo;ho recuperato da una issue dove ho scoperto che altre persone hanno avuto il mio stesso mal di testa)\nGitHub ha avviato il processo di creazione del certificato su Let&rsquo;s Encrypt, successivamente ho riconfigurato i record DNS come in precedenza e finalmente.\nNon ho cosi tanta memoria ma Wikipedia attribuisce la prima release del servizio al 2008.&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/it\/2022\/06\/01\/github-pages-ed-il-confusionario-processo-per-applicare-https\/","summary":"<p>Molti di voi sapranno che ormai da un po\u2019 di tempo, 13 anni<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\">1<\/a><\/sup> ormai, GitHub offre un servizio chiamato <a href=\"https:\/\/pages.github.com\/\">Pages<\/a> che consente di ospitare siti statici, molto comodo per ospitare blog e documentazione.<\/p>\n<p>Per questo non \u00e8 una novit\u00e0 che questo blog, come molti altri, sia ospitato proprio li. Ed il motivo non \u00e8 perch\u00e9&rsquo; &ldquo;fa figo&rdquo; ma molto pi\u00f9 concreto e venale.<br>\nUno degli obbiettivi che mi ero prefissato era quello di non farlo diventare una spesa viva, per questo scelsi l&rsquo;accoppiata <a href=\"https:\/\/gohugo.io\/\">HUGO<\/a> + GitHub Pages, una scelta che oggi rifarei! Per una volta mi posso dare una pacca sulla spalla \ud83d\ude42.<\/p>","title":"GitHub Pages ed il confusionario processo per applicare HTTPS"},{"content":" Recentemente mi \u00e8 stato chiesto di realizzare uno spike1 per valutare la fattibilit\u00e0 nella realizzazione di un&rsquo;architettura micro frontends con Blazor Server.\nTi dico subito che \u00e8 stato un fallimento; ma andiamo con ordine, analizzando dapprima la declinazione del termine fallimento e le ragioni che mi hanno portato ad usarlo per poi cercare di ricapitolare quanto emerso da questa esplorazione che mi ha fatto giungere a questa conclusione.\nMi piace molto la definizione che da Treccani.\nRiconoscere l&rsquo;inutilit\u00e0 dei propri sforzi, l&rsquo;impossibilit\u00e0 e incapacit\u00e0 di raggiungere gli scopi fissati, rinunciando definitivamente alla lotta, all&rsquo;azione.\n&ndash; Treccani\nLo trovo particolarmente appropriato perch\u00e9 utilizza il termine scopi fissati, e quindi quali sono questi scopi?\nIl contesto conta. Nulla si fa per caso, e questa non \u00e8 certo un&rsquo;eccezione. Il lavoro svolto \u00e8 parte di un contesto pi\u00f9 ampio che riguarda la necessit\u00e0 di migrare una serie di applicativi ASP.NET MVC 5 ad ASP.NET Core combinata alla volont\u00e0 di rendere l&rsquo;attuale architettura pi\u00f9 flessibile introducendo il concetto di programmazione modulare2.\nSenza girarci troppo intorno, lo scopo finale era quello di misurare la fattibilit\u00e0 di &ldquo;realizzare&rdquo; un&rsquo;architettura a micro frontends renderizzati lato server grazie a Blazor Server.\nA tal proposito sul blog di Martin Fowler \u00e8 presente un articolo bell&rsquo;articolo di Cam Jackson nel quale viene fatta una panoramica su questa architettura e dal quale ho tradotto la loro definizione di micro frontends\nUno stile architettonico in cui le applicazioni frontend, consegnabili in modo indipendente, sono composte in un insieme pi\u00f9 grande.\n&ndash; Thoughtworks su martinfowler.com\nHo messo realizzare fra virgolette in quanto la pubblicazione dei vari siti sarebbe avvenuta sempre e soltanto in modo unitario.\nMagari affronteremmo questo problema in un prossimo post.\nNon tutte le ciambelle riescono col buco. Andando dritti al punto, la motivazione principe che ha decretato il fallimento \u00e8 legata all&rsquo;impossibilit\u00e0 di dare completa autonomia ai team, per due principali motivi ben precisi.\nOmonimia nel supporto alle pagine ed alle viste Razor. Per comporre il sito ogni frontend viene contenuto all&rsquo;interno di una libreria di classi Razor la quale contiene anche la vista che si occupa di fare hosting dell&rsquo;applicazione Blazor.\nQuesto \u00e8 reso possibile grazie alla funzionalit\u00e0 esposta dal SDK che consente ad una web app di utilizzare viste, pagine Razor o layout da librerie di classi e, come definito nella documentazione ufficiale, in caso di omonimia la precedenza viene data alla vista, pagina, layout presente nella web app.\nNel mio caso mi trovo in una situazione del genere\nFigura 1: una applicazione ASP.NET Core che referenzia due Razor Class Library che rappresentano due moduli.\ndove entrambi i moduli internamente fanno uso di layout contenuti al percorso \/Pages\/Shared\/_Layout.cshtml.\nEcco, in questo caso accadrebbe che uno dei due team sarebbe scontento in quanto, se andasse bene vedrebbe la sua applicazione renderizzata all&rsquo;interno di un altro layout, nel peggiore dei casi una parte o tutte le viste andrebbero in errore (es. una vista cerca di valorizzare una sezione non dichiarata nel layout).\nE notiamo bene che entrambi i moduli eseguiti indipendentemente si comporterebbero come atteso.\nLe rotte, il percorso di base che non vuole funzionare. Ho che almeno io non sono riuscito a far funzionare.\nAnche in questo caso, seguendo il principio dell&rsquo;autonomia, il desiderata era quello di separare le rotte del modulo da quelle del contenitore, per esempio all&rsquo;interno del Modulo A avremmo trovato \/ oppure \/index mentre dal punto di vista del contenitore le rotte sarebbero state \/module-a\/ o \/module-a\/index.\nQuello che ho trovato \u00e8 stata una &ldquo;coperta corta&rdquo;, quando funzionava la navigazione interna al modulo non funzionava la generazione di rotte utilizzando Anchor Tag Helper (ricordo che questo spike \u00e8 frutto di un processo di migrazione), in quanto per la realizzazione del requisito ho utilizzato il middleware UsePathBaseMiddleware.\nQuesto ha comportato che nella generazione dei link all&rsquo;interno del modulo verso l&rsquo;esterno venisse aggiunto sempre il \/module-a in testa all&rsquo;indirizzo anche quanto il collegamento avrebbe dovuto semplicemente puntare la contenitore.\nDiversamente utilizzando il middleware sarei stato costretto ad utilizzare il nome del modulo in testa a tutte le direttive @page.\nConclusioni. Tirando le somme di quanto fatto e ragionando a mente fredda potrei dire che qualcosa di buono ce lo possiamo comunque portare a casa, infatti, non abilitando il supporto alle pagine e viste Razor in una RCL3 ed evitando l&rsquo;utilizzo di Anchor Tag Helper nel markup HTML che contribuisce al rendering della vista non incorreremmo in questi problemi.\nUno spike \u00e8 un metodo di sviluppo del prodotto originato dalla programmazione estrema che utilizza il programma pi\u00f9 semplice possibile per esplorare potenziali soluzioni. Fonte Wikipedia.&#160;&#x21a9;&#xfe0e;\nLa programmazione modulare \u00e8 una tecnica di progettazione software che enfatizza la separazione della funzionalit\u00e0 di un programma in moduli indipendenti e intercambiabili, in modo tale che ognuno contenga tutto il necessario per eseguire solo un aspetto della funzionalit\u00e0 desiderata. Fonte Wikipedia.&#160;&#x21a9;&#xfe0e;\nLe librerie di classi Razor (RCL) sono state introdotte in ASP.NET Core 2.1 come metodo per impacchettare e distribuire componenti dell&rsquo;interfaccia utente da referenziare e utilizzare all&rsquo;interno di un&rsquo;applicazione host.&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/it\/2022\/05\/22\/micro-frontends-e-blazor-server-linizio-del-viaggio\/","summary":"Non sempre le ciambelle riescono col buco ma questo non vuol dire che non ci sia del buono in loro. Sono incappato in una di queste nel tentativo di realizzare un&rsquo;architettura a micro frontends con Blazor Server.","title":"Micro frontends e Blazor Server, l'inizio del viaggio"},{"content":"Recentemente il team Azure SDK ha rilasciato la prima versione stabile delle librerie per la gestione delle risorse.\nRaccolte sotto lo spazio dei nomi Azure.ResourceManager queste librerie andranno a sostituire tutte quelle attualmente presenti nello spazio dei nomi Microsoft.Azure.Management e a differenza delle precedenti saranno suddivide per servizio.\nDifferenze con Bicep e ARM templates. Se hai avuto modo di approvvigionare risorse Azure mediante uno di questi due pseudo-linguaggi hai sfruttato gli endpoint REST della risorsa deployments per la creazione dell&rsquo;infrastruttura richiesta mediante il passaggio di un template in formato JSON strutturato e validato da un JSON Schema.\nLe ragioni per cui prendere in considerazione l&rsquo;utilizzo dei template sono innumerevoli, oltre l&rsquo;integrazione con Visual Studio Code e Visual Studio \u00e8 possibile distribuire le risorse ottenendo risultati ripetibili, mantenere uno storico delle distribuzioni e valutare la conformit\u00e0 agli standard aziendali attraverso i criteri di Azure.\nAzure.ResourceManager.Resources non implementa \u201cnativamente\u201d questo concetto ma comunque ne consente l&rsquo;utilizzo in quanto attraverso la classe ArmDeploymentCollection abbiamo modo operare sugli stessi endpoint REST utilizzati da Bicep e ARM templates.\nCreare una nuova distribuzione. Per ottenere una nuova distribuzione dobbiamo dotarci di un ArmClient passandogli un auth token con TokenCredential.\n1 2 3 using Azure.Identity; using Azure.ResourceManager; ArmClient client = new ArmClient(new DefaultAzureCredential()); Che ci consentir\u00e0 di accedere alla sottoscrizione predefinita, in base alle credenziali fornite, con await client.GetDefaultSubscriptionAsync() oppure all&rsquo;ambito desiderato creando un identificativo della risorsa di interesse con ResourceIdentifier e passandolo ad uno dei metodi client.GetSubscriptionResource(id) o client.GetManagementGroupResource(id) o ancora client.GetResourceGroupResource(id).\nAd esempio:\n1 2 3 4 var id = ManagementGroupResource.CreateResourceIdentifier(&#34;MY_MNGM_GROUP&#34;); var managementGroup = client.GetManagementGroupResource(id); ArmDeploymentCollection deploymentCollection = managementGroup.GetArmDeployments(); Non ci resta che creare un&rsquo;istanza di ArmDeploymentContent al quale possiamo passare il link ad un template esistente\n1 2 3 4 5 6 7 var deployment = new ArmDeploymentContent(new ArmDeploymentProperties(ArmDeploymentMode.Incremental) { TemplateLink = new ArmDeploymentTemplateLink { Uri = new Uri(&#34;https:\/\/raw.githubusercontent.com\/Azure\/azure-docs-json-samples\/master\/azure-resource-manager\/emptyrg.json&#34;) }, }); oppure utilizzare la propriet\u00e0 Template per definire uno nostro.\nIn questo caso sar\u00e0 necessario costruire un oggetto di tipo BinaryData che rappresenti un JSON valido, ad esempio serializzando un dizionario.\n1 2 3 4 5 6 7 8 9 var emptyDeployment = new Dictionary&lt;string, object&gt;(); emptyDeployment.Add(&#34;$schema&#34;, &#34;https:\/\/schema.management.azure.com\/schemas\/2019-04-01\/deploymentTemplate.json#&#34;); emptyDeployment.Add(&#34;contentVersion&#34;, &#34;1.0.0.0&#34;); emptyDeployment.Add(&#34;resources&#34;, Array.Empty&lt;object&gt;()); var deployment = new ArmDeploymentContent(new ArmDeploymentProperties(ArmDeploymentMode.Incremental) { Template = BinaryData.FromObjectAsJson(emptyDeployment) }); E successivamente effettuare la chiamata al metodo CreateOrUpdate per ottenere lo scopo.\n1 2 3 4 deploymentCollection.CreateOrUpdate( deploymentName: Guid.NewGuid().ToString(), content: deployment, waitUntil: WaitUntil.Started); Riferimenti utili. introduzione alla nuova esperienza di sviluppo: comparativa fra le vecchie librerie e le nuove principi progettuali alla base dell&rsquo;SDK utili in caso doveste aprire segnalazioni di problemi incontrati nell&rsquo;utilizzo lista comprensiva delle librerie attualmente in sviluppo: https:\/\/azure.github.io\/azure-sdk\/releases\/latest\/index.html?search=Azure.ResourceManager. ","permalink":"https:\/\/binick.blog\/it\/2022\/05\/09\/utilizzare-i-modelli-arm-con-azure-sdk-per-.net\/","summary":"<p>Recentemente il team <a href=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/azure-sdk-release-april-2022\/\"><em>Azure SDK<\/em><\/a> ha rilasciato la prima versione stabile delle librerie per la gestione delle risorse.<br>\nRaccolte sotto lo spazio dei nomi <code>Azure.ResourceManager<\/code> queste librerie andranno a sostituire tutte quelle attualmente presenti nello spazio dei nomi <code>Microsoft.Azure.Management<\/code> e a differenza delle precedenti saranno suddivide per servizio.<\/p>\n<h2 id=\"differenze-con-bicep-e-arm-templates\">Differenze con <em>Bicep<\/em> e <em>ARM templates<\/em>.<\/h2>\n<p>Se hai avuto modo di approvvigionare risorse <em>Azure<\/em> mediante uno di questi due pseudo-linguaggi hai sfruttato gli endpoint REST della risorsa <a href=\"https:\/\/docs.microsoft.com\/rest\/api\/resources\/deployments\"><em>deployments<\/em><\/a> per la creazione dell&rsquo;infrastruttura richiesta mediante il passaggio di un <a href=\"https:\/\/docs.microsoft.com\/azure\/azure-resource-manager\/templates\/overview\"><em>template<\/em><\/a> in formato <em>JSON<\/em> strutturato e validato da un <em>JSON Schema<\/em>.<\/p>","title":"Utilizzare i modelli ARM con Azure SDK per .NET"},{"content":"Non sono uno scrittore, non lo sono mai stato e questa cosa la so sin dai temi a scuola. Ogni volta superare la colonna e mezzo era un&rsquo;impresa.\nPubblicare articoli con regolarit\u00e0 mi porta via molto tempo, e non solo strettamente legato alla scrittura. Per questo ho tratto inspirazione da Troy Hunt ed ho pensato che creare un riepilogo mensile per aggiornarvi sul mio attuale stato e sulle possibili direzioni future potesse essere un buon investimento di tempo.\nQuesta cos\u00e0, se riuscir\u00f2 a perseguirla nel tempo, sar\u00e0 utile anche a me un domani.\nRecap 0. Esattamente un mese fa da oggi ho annunciavo un nuovo side project. Bene, sono riuscito a creare la prima strategia riguardante la nomenclatura delle risorse in Azure.\nIl prossimo traguardo \u00e8 quello di definire le altre due strategie, relative alla localizzazione ed al tagging.\nHo inoltre in mente di creare un libreria in Python cosi da poter integrare il tutto nella Azure CLI.\nRiferimenti. Build your own Azure CLI Extensions: ottimo articolo su come creare una estensione della Azure CLI. ","permalink":"https:\/\/binick.blog\/it\/2022\/04\/29\/monthly-recap-0\/","summary":"<p>Non sono uno scrittore, non lo sono mai stato e questa cosa la so sin dai temi a scuola. Ogni volta superare la colonna e mezzo era un&rsquo;impresa.<\/p>\n<p>Pubblicare articoli con regolarit\u00e0 mi porta via molto tempo, e non solo strettamente legato alla scrittura. Per questo ho tratto inspirazione da <a href=\"https:\/\/www.troyhunt.com\/tag\/weekly-update\/\">Troy Hunt<\/a> ed ho pensato che creare un riepilogo mensile per aggiornarvi sul mio attuale stato e sulle possibili direzioni future potesse essere un buon investimento di tempo.<\/p>","title":"Monthly recap 0"},{"content":"","permalink":"https:\/\/binick.blog\/it\/2022\/04\/14\/migrare-un-database-sql-server-on-prem-in-azure-senza-downtime\/","summary":"Il lift-and-shift \u00e8 la strategia che consente la migrazione su Cloud pi\u00f9 rapida, meno laboriosa e (almeno inizialmente) meno costosa rispetto ad altri processi.<br>\nIn questo articolo vedremo come \u00e8 possibile migrare un database SQL Server senza generare interruzioni sui servizi gi\u00e0 in opera.","title":"Migrare un database SQL Server on-prem in Azure senza downtime"},{"content":"Qualche anno fa, quando ero un pendolare andavo a lavoro in auto, lungo il tragitto c\u2019era un tratto di strada di campagna alberato che costeggiava un torrente. All\u2019interno di questa zona era presente una chicane molto stretta in uscita immediatamente successiva ad una lieve discesa che seguiva un lungo rettifilo. Data la presenza del torrente e l\u2019ombra permanente causata degli alberi non era cosa rara che in alcune mattinate d&rsquo;inverno vi fosse la presenza di ghiaccio.\nNon ho mai avuto incidenti l\u00ec in quanto ero a conoscenza del potenziale pericolo e nonostante il rettifilo portasse a spingere sull\u2019acceleratore mi trattenevo.\nCosa voglio dirvi con questo aneddoto?\nChe prevenire \u00e8 meglio che curare?\nNon proprio, il messaggio \u00e8 pi\u00f9 sottile e riguarda l\u2019istinto e la coscienza.\nCosa succederebbe se qualcuno passasse di l\u00ec per caso in una di quelle mattine?\nE magari anche in ritardo per il suo appuntamento?\nCon molta probabilit\u00e0 sarebbe costretto a chiamare il carroattrezzi in quanto non consapevole della presenza di ghiaccio avrebbe pestato a fondo il pedale del freno per ridurre la velocit\u00e0 ad affrontare la curva. Con conseguente perdita di aderenza e ad auto in fossa.\nQuali sarebbero le potenziali conseguente?\nSupponiamo che dopo questa sfortunata \u201cavventura&quot; l\u2019autista esca incolume dall\u2019auto, quali sarebbero le altre conseguenze?\nDirei due, un portafogli alleggerito ed un appuntamento mancato.\nUn tipico approccio all\u2019OpEx. Immagino vi starete domandando quale sia il fine ed il perch\u00e9 di questa parabola.\nDovete sapere che qualche tempo fa ho partecipato ad alcune riunioni inerenti alla migrazione di un applicativo aziendale ad uso interno in Azure nelle quali sono emerse molte problematiche dovute ai permessi assegnati agli utenti.\nProblemi che hanno causato lo slittamento del rilascio in produzione di un applicativo aziendale ad uso interno di oltre due settimane.\nProviamo, con non propriamente poco sforzo, a trasporre la parabola dello sfortunato autista all\u2019interno di questo contesto; possiamo identificare la strada come il cloud, la persona alla guida dell\u2019auto come l\u2019azienda. E direi di fermarci qui per il momento.\nTipicamente quando un\u2019azienda si avvicina al cloud uno dei principali motivi di preoccupazione \u00e8 la gestione dei costi1.\nImmaginiamo di essere un membro del team di security operation, abituato ad operare su di un set di macchine predeterminato che adesso si ritrova con un potenziale parco macchine infinito ed un monito da parte del suo manager di area che gli dice di dover contenere le spese.\nL\u2019unica cosa che conosce di pi\u00f9 simile a ci\u00f2 che ha usato finora \u00e8 il controllo dell\u2019accesso basato sui ruoli di Active Directory che trova il suo corrispettivo Azure RBAC configurabile anche da Azure Active Directory.\nVoi cosa fareste? Io credo che limiterei gli accessi a tutti gli utenti dando solo i permessi minimi necessari ai membri del team di sviluppo, ma penso che anche voi agireste cos\u00ec.\nE questo \u00e8 quello che il team ha fatto, per questo ha predisposto due gruppi di risorse, uno per ospitare tutte le risorse legate a tematiche di networking ed uno per il team di sviluppo dando loro il ruolo di Contributor per quest\u2019ultimo.\nScivolando in un uso improprio dei gruppi di risorse in modo improprio in quanto alcune risorse come per esempio il servizio Azure Kubernetes si appoggia ad un terzo gruppo di risorse per ospitare i nodi dei pool di agenti condiviso fra noi ed il servizio stesso.\nEducare piuttosto che imporre. Il team di SecOps ha fallito in quanto non a conoscenza del significato del termine Cloud Governance e gli strumenti che Azure offre a supporto.\nOvviamente il team ha agito in buona fede cercando di limitare l\u2019ambito2 di azione di ogni team.\nPensando di raggiungere due obbiettivi: controllo dei costi3 e sicurezza4.\nEcco che adesso abbiamo gli elementi necessari per riprendere la trasposizione iniziata precedentemente e identificare l\u2019ambito2 nel giaccio, la data di rilascio nell\u2019appuntamento e le cinque discipline della governance del cloud nella consapevolezza.\nEcco che per cercare di aumentare questa consapevolezza ho creato questo repository\nbinick \/ oh-my-azure-playground il cui intento \u00e8 quello di definire degli standard basandosi sulle migliori pratiche emerse in tematiche come denominazione delle risorse, gestione dei tag e della localizzazione.\nSulle quali sar\u00e0 poi possibile definire dei pattern per la definizione di budget3.\nNel corso degli anni ho iniziato diversi side project ma mai nessuno ha avuto un post come questo.\nLo considero come un primo passo verso un impegno concreto, se volete approfondire o sentite la necessit\u00e0 di contribuire non esitate a contattarmi \ud83d\ude42.\nCapEx vs OpEx in Cloud Computing&#160;&#x21a9;&#xfe0e;\nComprendere l&rsquo;ambito per il controllo degli accessi in base al ruolo di Azure&#160;&#x21a9;&#xfe0e;&#160;&#x21a9;&#xfe0e;\nChe cos&rsquo;\u00e8 Gestione dei costi e fatturazione?&#160;&#x21a9;&#xfe0e;&#160;&#x21a9;&#xfe0e;\nIntroduzione alla sicurezza di Azure&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/it\/2022\/03\/29\/un-nuovo-side-project\/","summary":"<p>Qualche anno fa, quando ero un pendolare andavo a lavoro in auto, lungo il tragitto c\u2019era un tratto di strada di campagna alberato che costeggiava un torrente. All\u2019interno di questa zona era presente una chicane molto stretta in uscita immediatamente successiva ad una lieve discesa che seguiva un lungo rettifilo.\nData la presenza del torrente e l\u2019ombra permanente causata degli alberi non era cosa rara che in alcune mattinate d&rsquo;inverno vi fosse la presenza di ghiaccio.<\/p>","title":"Un nuovo side project"},{"content":" ","permalink":"https:\/\/binick.blog\/it\/2022\/03\/15\/connettersi-ad-azure-sql-in-modo-sicuro-con-le-identit%C3%A0-gestite\/","summary":"In quanto sviluppatori, siamo abituati a maneggiare chiavi, stringhe di connessione, certificati, nomi utente e password quotidianamente. Forse, proprio per la frequenza con la quale maneggiamo queste informazioni a volte pu\u00f2 capitare di abbassare la guardia e non dare loro il trattamento che meriterebbero, esponendoci inconsapevolmente a rischi non banali.","title":"Connettersi ad Azure SQL in modo sicuro con le identit\u00e0 gestite"},{"content":"Ho iniziato a lavorare in modalit\u00e0 remota a Marzo 2020, la ragione immagino la conosciamo tutti.\nComunque se un extra terrestre dovesse leggere questo post qua potr\u00e0 trovare maggiori informazioni https:\/\/wikipedia.org\/wiki\/COVID-19.\nL&rsquo;esperienza \u00e8 stata quella di molti immagino, un uso massimo ed indiscriminato di piattaforme di comunicazione ed orecchi fumanti a fine giornata.\nQuest&rsquo;esperienza \u00e8 andata avanti all&rsquo;incirca per un anno e mezzo, 16 mesi per la precisione, fino a Luglio 2021 quando sono entrato in managed\/designs.\nQui ho trovato un ambiente differente, alcuni lo definirebbero smart, votato alla crescita personale ed al miglioramento continuo, dove autonomia e fiducia sono due pilastri sulle quali si basa la collaborazione giornaliera.\nPrologo. Non sono mai stato un utilizzatore delle liste di cose da fare, forse per inesperienza o forse per qualche mia convinzione a me sconosciuta. Sta di fatto che il fallire sistematico nel seguire la lista della spesa ne \u00e8 una prova &ldquo;Nicola non \u00e8 capace a gestire le liste&rdquo;.\nUna volta presa consapevolezza di ci\u00f2 mi sono messo alla ricerca di possibili pattern e\/o metodologie individuandone alcune che mi stanno accompagnando da un paio di mesi.\nLa mia inbox non \u00e8 la mail. Ho compreso che quello di cui ho bisogno non \u00e8 una lista di attivit\u00e0 da fare ma piuttosto una lista di cose che vorrei fare o che in qualche modo attira il mio interesse, credo che a livello inconscio il mio cervello prenda con ottimismo la mancanza di quel &ldquo;da&rdquo; che genera pressione per cose verso le quali non dovrebbe esserci.\nHo tre mail, quella aziendale ed altre due storiche che mi porto dietro da almeno un decennio, tutte e tre seguono la filosofia dell&rsquo;Inbox Zero di Merlin Mann. Al momento le sfoglio due volte al giorno, all&rsquo;incirca prima di pranzo e prima della fine della giornata, questi slot sono degli appuntamenti ricorrenti sul calendario fino al prossimo 29 di Giugno, vedremo se saranno prolungati ma credo di si.\nLa regola \u00e8 molto semplice:\n\u00e8 importante e deve essere eseguita in un preciso momento: viene creato un appuntamento sul calendario e viene archiviata nella relativa casella di posta \u00e8 importante: finisce nell&rsquo;inbox e viene archiviata mi interessa: finisce nell&rsquo;inbox e viene eliminata non mi interessa: finisce subito nel cestino In questo modo ho sempre le caselle di posta libere e riesco a mantenere l&rsquo;attenzione sullo su quella decina di mail.\nSe arriva una mail che richiede un&rsquo;interazione attiva non la eseguir\u00f2 subito ma come per le altre sottostar\u00e0 alle regole qui sopra.\nUna rana al giorno \u00e8 sufficiente. L&rsquo;altra tecnica per me illuminante \u00e8 stata l&rsquo;aver scoperto la regola dell'1-3-51 che trova fondamento sulla pratica di mangiare una rana appena svegli2. Ovviamente non fisicamente, non mi vorrei mai svegliare ed ultimamente dormo anche poco!\nPer cui il giorno prima faccio la lista di quello che vorrei fare l&rsquo;indomani applicando una sorta di prioritizzazione delle attivit\u00e0 abbastanza empirica al momento stando sempre attendo che vi sia almeno una rana ed eventualmente altre attivit\u00e0 riempitive.\nEpilogo. Devo essere onesto, all\u2019inizio ero scettico sull\u2019impiegare del tempo organizzare il mio domani. Devo riscredermi, il beneficio di scaricare il cervello dall&rsquo;onere di pensare a cosa fare per non correre il rischio di perderla per sempre \u00e8 una cosa da non sottovalutare.\nAl momento la rigidit\u00e0 del calendario e la flessibilit\u00e0 che mi lascia la lista 1-3-5 sono un buon connubio. Solo il tempo sapr\u00e0 dire se \u00e8 una scelta per me vincente.\nWhy You Never Finish Your To-Do Lists at Work (And How to Change That) di Alex Cavoulacos&#160;&#x21a9;&#xfe0e;\nEat That Frog: Brian Tracy Explains the Truth About Frogs di Brian Tracy&#160;&#x21a9;&#xfe0e;\n","permalink":"https:\/\/binick.blog\/it\/2022\/02\/18\/quella-volta-nella-quale-ho-assaggiato-una-rana\/","summary":"<p>Ho iniziato a lavorare in modalit\u00e0 remota a Marzo 2020, la ragione immagino la conosciamo tutti.<\/p>\n<blockquote>\n<p>Comunque se un extra terrestre dovesse leggere questo post qua potr\u00e0 trovare maggiori informazioni <a href=\"https:\/\/wikipedia.org\/wiki\/COVID-19\">https:\/\/wikipedia.org\/wiki\/COVID-19<\/a>.<\/p>\n<\/blockquote>\n<p>L&rsquo;esperienza \u00e8 stata quella di molti immagino, un uso massimo ed indiscriminato di piattaforme di comunicazione ed orecchi fumanti a fine giornata.<br>\nQuest&rsquo;esperienza \u00e8 andata avanti all&rsquo;incirca per un anno e mezzo, 16 mesi per la precisione, fino a Luglio 2021 quando sono entrato in <a href=\"https:\/\/www.manageddesigns.it\/\"><em>managed\/designs<\/em><\/a>.<\/p>","title":"Quella volta nella quale ho assaggiato una rana"},{"content":"In un articolo precedente abbiamo visto Arricchire token JWT emessi da Azure Active Directory B2C.\nIn quell&rsquo;articolo abbiamo parlato di come sia possibile aggiungere ad un JWT informazioni esterne a Microsoft Graph mediante l&rsquo;uso di una Logic App ed un Blob Storage.\nIn questo invece vedremo come sia possibile creare una soluzioni che integri Azure Active Directory B2C.\nSeguendo la traccia di quanto trattato nel precedente articolo vedremo come salvare su Blob Storage dati fittizi alla registrazione di un utente.\nNote Nel resto dell&rsquo;articolo ci sono riferimenti a risorse e concetti trattati nel precedente articolo al quale si rimanda. Panoramica della soluzione. La soluzione \u00e8 cosi composta:\nComposizione della soluzione\nread-customer-details-identity-la: rappresenta l&rsquo;api il cui scopo \u00e8 reperire il contenuto del blob da customersstgacc (lo storage account) customer-register-tpc: \u00e8 il topic nel quale sono collezionati gli eventi di creazione di un nuovo utente customer-identity-details-filler-la: rappresenta l&rsquo;api al quale spetta l&rsquo;onere di generare dati fittizi che poi saranno salvati all&rsquo;interno di un blob sullo customersstgacc contoso-b2c: \u00e8 il servizio di gestione degli accessi e delle identit\u00e0 offerto da Azure Introduzione ad Azure Event Grid. In Azure esiste un&rsquo;implementazione del pattern publish\/subscribe concepita per agevolare l&rsquo;integrazione e la gestione delle risorse mediante un paradigma di sviluppo ad eventi.\nMediante Event Grid sar\u00e0 quindi possibile sottoscriversi a sorgenti di messaggi built-in attraverso una serie di gestori.\nQual&rsquo;ora questo non fosse sufficiente \u00e8 comunque possibile creare dei topic personalizzati ai quali sar\u00e0 possibile sottoscriversi per riceverne gli eventi.\nCreazione di un topic personalizzato. Per la creazione di un topic \u00e8 possibile fare riferimento a questa guida.\nUna scelta da fare al momento della creazione del topic riguarda lo schema del contenuto della richiesta HTTP utilizzato. Gli schemi supportati al momento sono:\nEvent Grid Schema Cloud Event Schema Custom Input Schema, questo schema richieder\u00e0 la creazione di un&rsquo;associazione fra le propriet\u00e0 dell&rsquo;oggetto in ingresso e quelle richieste dallo Event Grid Schema. Il messaggio usato in questo caso ha la seguente struttura\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ { &#34;data&#34;: { &#34;objectId&#34;: &#34;25100647-****-4571-****-b03e4ce72d02&#34; \/\/ l&#39;identificativo utile ad identificare l&#39;utente }, &#34;id&#34;: &#34;25100647-****-4571-****-b03e4ce72d02&#34;, \/\/ l&#39;identificativo univoco del messaggio, lo stesso di `data.objectId` in qesto caso &#34;eventType&#34;: &#34;Microsoft.ActiveDirectory&#34;, &#34;subject&#34;: &#34;*.onmicrosoft.com&#34;, &#34;dataVersion&#34;: &#34;1.0&#34;, &#34;metadataVersion&#34;: &#34;1&#34;, &#34;eventTime&#34;: &#34;2021-12-03T21:04:03.8504745Z&#34;, &#34;topic&#34;: &#34;\/subscriptions\/{your-subscription-id}\/resourceGroups\/{your-resource-group}\/providers\/Microsoft.EventGrid\/topics\/{your-event-grid-topic}&#34; } ] Emissione dell&rsquo;evento di registrazione. L&rsquo;invio degli eventi verso il topic avviene utilizzando un RESTful technical profile.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 &lt;TechnicalProfile Id=&#34;AAD-UserEmitRegistrationEvent&#34;&gt; &lt;DisplayName&gt;Emit user registration event to Event Grid.&lt;\/DisplayName&gt; &lt;Protocol Name=&#34;Proprietary&#34; Handler=&#34;Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&#34; \/&gt; &lt;Metadata&gt; &lt;Item Key=&#34;ServiceUrl&#34;&gt;{Settings:CustomerRegisteredTopicUrl}&lt;\/Item&gt; &lt;Item Key=&#34;AuthenticationType&#34;&gt;ApiKeyHeader&lt;\/Item&gt; &lt;Item Key=&#34;SendClaimsIn&#34;&gt;Body&lt;\/Item&gt; &lt;Item Key=&#34;ClaimUsedForRequestPayload&#34;&gt;userRegisterEvent&lt;\/Item&gt; &lt;Item Key=&#34;DefaultUserMessageIfRequestFailed&#34;&gt;Cannot process your request right now, please try again later.&lt;\/Item&gt; &lt;\/Metadata&gt; &lt;CryptographicKeys&gt; &lt;Key Id=&#34;aeg-sas-key&#34; StorageReferenceId=&#34;B2C_1A_CustomerRegisteredTopicSas&#34; \/&gt; &lt;\/CryptographicKeys&gt; &lt;InputClaimsTransformations&gt; &lt;InputClaimsTransformation ReferenceId=&#34;GetSystemDateTime&#34; \/&gt; &lt;InputClaimsTransformation ReferenceId=&#34;GenerateRegistrationEventRequest&#34; \/&gt; &lt;\/InputClaimsTransformations&gt; &lt;InputClaims&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;userRegisterEvent&#34; \/&gt; &lt;\/InputClaims&gt; &lt;PersistedClaims&gt; &lt;PersistedClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; \/&gt; &lt;\/PersistedClaims&gt; &lt;UseTechnicalProfileForSessionManagement ReferenceId=&#34;SM-AAD&#34; \/&gt; &lt;\/TechnicalProfile&gt; Questo frammento di markup tradotto in comando curl, per maggiore esplicabilit\u00e0, risulterebbe cosi:\n1 curl -X POST -H &#34;aeg-sas-key: $key&#34; -d &#34;$event&#34; $endpoint dove i requisiti di autenticazione vengono soddisfatti dal metadato AuthenticationType al quale viene associata la chiave crittografica aeg-sas-key il cui valore viene recuperato dalla chiave B2C_1A_CustomerRegisteredTopicSas presente nella collezione delle chiavi dei criteri.\nTL;DR La scelta dello schema del topic in questo esempio \u00e8 stata guidata dalle limitazioni al momento imposte dal profilo tecnico RESTful riguardo alle possibilit\u00e0 di costruzione della richiesta HTTP, infatti per una combinazione di criteri non risulta possibile passare informazioni nelle intestazioni e nel corpo della richiesta allo stesso tempo.\nCi\u00f2 rende impossibile inviare verso un topic schemi di tipo Cloud Event in quanto il protocollo, nella versione 1.0 richiede la presenza di un&rsquo;intestazione obbligatoria. Ben pi\u00f9 complessa \u00e8 la creazione del corpo della richiesta per la quale risultano necessario:\nutilizzare le InputClaimsTransformation aggiungere due attestazioni all&rsquo;interno del bagaglio userRegisterEvent e systemDateTime entrambe di tipo stringa. Infine il profilo tecnico \u00e8 stato aggiunto fra i profili tecnici di validazione di LocalAccountSignUpWithLogonEmail in modo tale che l&rsquo;evento venga emesso solamente in fase di registrazione di un&rsquo;utente.\nUtilizzo delle trasformazioni delle attestazioni. Durante la creazione di criteri personalizzati potremmo avere la necessit\u00e0 di eseguire calcoli, come ad esempio il numero di tentativi di autenticazione, che seppur molto semplici risulterebbero impossibili senza l&rsquo;esecuzioni di funzioni.\nQuesto requisito trova espressivit\u00e0 tramite le ClaimsTransformation il cui riferimento delle trasformazioni delle attestazioni contiene la lista completa delle trasformazioni utilizabili.\nNell&rsquo;esempio sono stati utilizzati i metodi GetCurrentDateTime e GenerateJson\n1 2 3 4 5 &lt;ClaimsTransformation Id=&#34;GetSystemDateTime&#34; TransformationMethod=&#34;GetCurrentDateTime&#34;&gt; &lt;OutputClaims&gt; &lt;OutputClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; TransformationClaimType=&#34;currentDateTime&#34; \/&gt; &lt;\/OutputClaims&gt; &lt;\/ClaimsTransformation&gt; GetSystemDateTime ha lo scopo di valorizzare l&rsquo;attestazione systemDateTime\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 &lt;ClaimsTransformation Id=&#34;GenerateRegistrationEventRequest&#34; TransformationMethod=&#34;GenerateJson&#34;&gt; &lt;InputClaims&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;objectId&#34; TransformationClaimType=&#34;0.data.objectId&#34; \/&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;objectId&#34; TransformationClaimType=&#34;0.id&#34; \/&gt; &lt;InputClaim ClaimTypeReferenceId=&#34;systemDateTime&#34; TransformationClaimType=&#34;0.eventTime&#34; \/&gt; &lt;\/InputClaims&gt; &lt;InputParameters&gt; &lt;InputParameter Id=&#34;0.dataVersion&#34; DataType=&#34;string&#34; Value=&#34;1.0&#34; \/&gt; &lt;InputParameter Id=&#34;0.eventType&#34; DataType=&#34;string&#34; Value=&#34;Microsoft.ActiveDirectory&#34; \/&gt; &lt;InputParameter Id=&#34;0.subject&#34; DataType=&#34;string&#34; Value=&#34;{Settings:Tenant}&#34; \/&gt; &lt;\/InputParameters&gt; &lt;OutputClaims&gt; &lt;OutputClaim ClaimTypeReferenceId=&#34;userRegisterEvent&#34; TransformationClaimType=&#34;outputClaim&#34; \/&gt; &lt;\/OutputClaims&gt; &lt;\/ClaimsTransformation&gt; GenerateRegistrationEventRequest ha invece l&rsquo;onere di costruire il JSON e valorizzare l&rsquo;attestazione userRegisterEvent.\nConclusioni. In questo articolo abbiamo visto come mediante Identity Experience Framework sia possibile integrare un tenant B2C con la nostra infrastruttura ed aprire eventuali scenari di sviluppo interessanti.\nPer farlo abbiamo toccato Azure Event Grid e come creare un Event Grid Topic.\nInfine come sia possibile manipolare delle attestazioni ed utilizzarle all&rsquo;interno dei profili tecnici.\nSe foste interessati all\u2019esempio completo lo potrete trovare al seguente indirizzo https:\/\/github.com\/binick\/samples\/tree\/master\/src\/enrich-a-jwt-token-with-ief.\n","permalink":"https:\/\/binick.blog\/it\/2022\/01\/08\/sviluppare-soluzioni-integrate-con-active-directory-b2c-ed-azure-event-grid.\/","summary":"<p>In un articolo precedente abbiamo visto <a href=\"https:\/\/www.ugidotnet.org\/tip\/2873\/Arricchire-JWT-emessi-da-Active-Directory-B2C-con-criteri-personalizzati\" title=\"Arricchire token JWT emessi da Azure Active Directory B2C.\" target=\"_blank\">Arricchire token JWT emessi da Azure Active Directory B2C<\/a>.<\/p>\n<p>In quell&rsquo;articolo abbiamo parlato di come sia possibile aggiungere ad un JWT informazioni esterne a <em>Microsoft Graph<\/em> mediante l&rsquo;uso di una <em>Logic App<\/em> ed un <em>Blob Storage<\/em>.<\/p>\n<p>In questo invece vedremo come sia possibile creare una soluzioni che integri <em>Azure Active Directory B2C<\/em>.<\/p>\n<p>Seguendo la traccia di quanto trattato nel precedente articolo vedremo come salvare su <em>Blob Storage<\/em> dati fittizi alla registrazione di un utente.<\/p>","title":"Sviluppare soluzioni integrate con Active Directory B2C ed Azure Event Grid."},{"content":" ","permalink":"https:\/\/binick.blog\/it\/2021\/12\/27\/arricchire-token-jwt-emessi-da-azure-active-directory-b2c\/","summary":"Personalizzare un JSON Web Token emesso da Azure Active Directory B2C con informazioni presenti su un sistema esterno \u00e8 possibile: \u00e8 sufficiente, infatti, sfruttare le possibilit\u00e0 di personalizzazione offerte dai criteri personalizzati.","title":"Arricchire token JWT emessi da Azure Active Directory B2C"},{"content":"","permalink":"https:\/\/binick.blog\/it\/about-me\/","summary":"Chi sono","title":"Chi sono"}]