{"id":25310,"date":"2018-11-01T12:06:39","date_gmt":"2018-11-01T11:06:39","guid":{"rendered":"http:\/\/help.qualiware.it\/qw-help\/?p=25310"},"modified":"2022-03-10T16:09:55","modified_gmt":"2022-03-10T15:09:55","slug":"importazione-dati-da-microsoft-dynamics-365-tramite-protocollo-odata-e-autenticazione-oauth2","status":"publish","type":"post","link":"https:\/\/help.qualiware.it\/qw-help\/importazione-dati-da-microsoft-dynamics-365-tramite-protocollo-odata-e-autenticazione-oauth2\/","title":{"rendered":"Importazione dati da Microsoft Dynamics 365 tramite protocollo oData e autenticazione oAuth2"},"content":{"rendered":"<p>Tramite uno script \u00e8 possibile importare dati da Microsoft Dynamics 365 utilizzando il protocollo oData e autenticandosi tramite il protocollo oAuth2.<\/p>\n<p>Queste tecnologie rappresentano lo stato dell&#8217;arte per quanto riguarda rispettivamente l&#8217;accesso ai dati RESTful e l&#8217;autenticazione a servizi in Cloud, e l&#8217;esempio sotto riportato \u00e8 quindi particolarmente importante costituendo un punto di partenza dal quale derivare altre soluzioni facendo uso di tali tecnologie.<\/p>\n<p><strong>Autenticazione oAuth2<\/strong><\/p>\n<p>Il protocollo oAuth2 viene utilizzato sia da Microsoft che da Google per l&#8217;accesso ai rispettivi servizi Cloud. Nel caso di Microsoft, e quindi di Dynamics 365, la gestione degli utenti avviene tramite Azure Active Directory (AAD), che fra le altre cose \u00e8 in grado di gestire l&#8217;appartenenza degli utenti stessi ad un dominio specifico (quello dell&#8217;azienda, es. &#8220;qualiware.it&#8221;). Pertanto ogni azienda potr\u00e0 usare il proprio dominio e registrare gli utenti sulle varie applicazioni.&nbsp;<\/p>\n<p>Una applicazione esterna, come ad esempio QualiWare, dovr\u00e0 effettuare apposite chiamate per autenticarsi e&nbsp; utilizzare i servizi messi a disposizione dall&#8217;applicazione Microsoft, e per fare questo non \u00e8 sufficiente disporre di un utente e una password, ma sar\u00e0 necessario registrare l&#8217;applicazione esterna stessa all&#8217;interno di AAD, per ottenere il cosiddetto Application ID (spesso chiamato anche Client ID) che andr\u00e0 specificato nelle suddette chiamate.&nbsp;<\/p>\n<p>L&#8217;autenticazione con utente e password \u00e8 possibile se l&#8217;applicazione esterna \u00e8 registrata come &#8220;Native&#8221;. Se viene registrata come &#8220;Web App\/Api&#8221;, \u00e8 necessario utilizzare il cosiddetto &#8220;Client Secret&#8221;, che viene reperito nella scheda di registrazione dell&#8217;app all&#8217;interno di Active Directory.<\/p>\n<p>Le immagini seguenti riportano un esempio di maschera di registrazione&nbsp; &#8220;Native&#8221; e &#8220;Web App\/Api&#8221; all&#8217;interno di AAD.<\/p>\n\n\t\t<style type=\"text\/css\">\n\t\t\t#gallery-1 {\n\t\t\t\tmargin: auto;\n\t\t\t}\n\t\t\t#gallery-1 .gallery-item {\n\t\t\t\tfloat: left;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\ttext-align: center;\n\t\t\t\twidth: 50%;\n\t\t\t}\n\t\t\t#gallery-1 img {\n\t\t\t\tborder: 2px solid #cfcfcf;\n\t\t\t}\n\t\t\t#gallery-1 .gallery-caption {\n\t\t\t\tmargin-left: 0;\n\t\t\t}\n\t\t\t\/* see gallery_shortcode() in wp-includes\/media.php *\/\n\t\t<\/style>\n\t\t<div id='gallery-1' class='gallery galleryid-25310 gallery-columns-2 gallery-size-large'><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Web-App.png'><img loading=\"lazy\" decoding=\"async\" width=\"591\" height=\"261\" src=\"https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Web-App.png\" class=\"attachment-large size-large\" alt=\"\" aria-describedby=\"gallery-1-25314\" srcset=\"https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Web-App.png 591w, https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Web-App-300x132.png 300w\" sizes=\"(max-width: 591px) 100vw, 591px\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-25314'>\n\t\t\t\tRegistrazione Web App\n\t\t\t\t<\/dd><\/dl><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Native-app.png'><img loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"263\" src=\"https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Native-app.png\" class=\"attachment-large size-large\" alt=\"\" aria-describedby=\"gallery-1-25315\" srcset=\"https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Native-app.png 584w, https:\/\/help.qualiware.it\/qw-help\/wp-content\/uploads\/AAD-Native-app-300x135.png 300w\" sizes=\"(max-width: 584px) 100vw, 584px\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-25315'>\n\t\t\t\tRegistrazione Native App\n\t\t\t\t<\/dd><\/dl><br style=\"clear: both\" \/>\n\t\t<\/div>\n\n<p>&nbsp;<\/p>\n<p><strong>Accesso ai dati tramite protocollo oData<\/strong><\/p>\n<p>Il protocollo oData \u00e8 un&#8217;implementazione del paradigma REST, e consente di effettuare operazioni di interrogazione e aggiornamento utilizzando il protocollo Web.<\/p>\n<p>Componendo opportunamente una URL, \u00e8 possibile specificare la tabella da interrogare, i filtri e l&#8217;operazione da effettuare. Ad, esempio, per reperire i primi 100 records della tabella Customers, si pu\u00f2 utilizzare una URL di questo tipo:<\/p>\n<pre>https:\/\/&lt;dominio applicazione&gt;.sandbox.ax.dynamics.com\/data\/CustomersV3?$top=100<\/pre>\n<p>Il risultato restituito \u00e8 un file JSon contenente i dati, che pu\u00f2 essere facilmente elaborato utilizzando la libreria Newtonsoft.Json gi\u00e0 inclusa nella piattaforma QualiWare, come vedremo nell&#8217;esempio successivo.<\/p>\n<p>Per ulteriori informazioni:<\/p>\n<ul>\n<li>Sull&#8217;utilizzo di oData in Dynamics 365 vedere <a href=\"https:\/\/docs.microsoft.com\/en-us\/dynamics365\/fin-ops-core\/dev-itpro\/data-entities\/odata\">qui<\/a>.<\/li>\n<li>Sulle differenze fra oData e REST vedere <a href=\"https:\/\/stackoverflow.com\/questions\/2458407\/difference-between-odata-and-rest-web-services\" class=\"broken_link\">qui<\/a>.<\/li>\n<\/ul>\n<p><strong>Esempio di codice<\/strong><\/p>\n<p>Il seguente codice effettua l&#8217;autenticazione a Dynamics 365 utilizzando nome utente e password, e reperisce i primi 1000 clienti visualizzandoli un un oggetto campo testo multiriga.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">Dim credential As New Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential(\"&lt;user&gt;\", \"&lt;password&gt;\")\r\nDim authContext As Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext = New Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(\"https:\/\/login.windows.net\/&lt;dominio azienda&gt;.com\", False)\r\n' Il ClientID (secondo parametro) \u00e8 l'Application ID registrato su Dynamics\r\n' NOTA: per potere usare utente e password, l'AppID deve essere registrata come \"Native\". \r\n' Se invece \u00e8 registrata come Web App\/Api, \u00e8 necessario ricevere \u201cClient Secret\u201d e \u201cClientID\u201d, e usare queste creare le credenziali\r\nDim res As Threading.Tasks.Task(Of Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult)\r\nres = Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.AcquireTokenAsync(authContext, \"https:\/\/&lt;dominio applicazione&gt;.sandbox.ax.dynamics.com\", \"8da6079a-390a-4eb5-9b08-eeda3066cb7b\", credential)\r\nres.Wait\r\nDim token As String = res.Result.AccessToken\r\n\r\nDim url As String = \"https:\/\/&lt;dominio&nbsp;applicazione&gt;.sandbox.ax.dynamics.com\/data\/CustomersV3?$top=1000\" ' Recupera i primi 1000 clienti\r\nDim request As System.Net.HttpWebRequest  \r\nDim response As System.Net.HttpWebResponse = Nothing  \r\nDim reader As System.IO.StreamReader  \r\n\r\nrequest = DirectCast(System.Net.WebRequest.Create(url), System.Net.HttpWebRequest)\r\nrequest.Headers.Add(\"Authorization\", \"Bearer \" + token) ' Usa il token recuperato sopra per l'autenticazione\r\nresponse = DirectCast(request.GetResponse(), System.Net.HttpWebResponse)\r\nreader = New System.IO.StreamReader(response.GetResponseStream())\r\n\r\nDim json As String\r\njson = reader.ReadToEnd()\t\t\r\n\r\nDim obj As Newtonsoft.Json.linq.JObject=Newtonsoft.Json.linq.JObject.Parse(json)\r\n\r\nDim i As integer\r\nform.findcontrol(\"Editor1\").Text=\"\"\r\nFor i=0 To CType(obj(\"value\"), Newtonsoft.Json.Linq.JArray).Count-1\r\n  form.findcontrol(\"Editor1\").text+=\"Codice: \"+ctype(obj(\"value\")(i)(\"CustomerAccount\"),Newtonsoft.Json.Linq.JValue).Value+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"Ragione sociale: \"+ctype(obj(\"value\")(i)(\"OrganizationName\"),Newtonsoft.Json.Linq.JValue).Value+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"E-mail:\"+Ctype(obj(\"value\")(i)(\"PrimaryContactEmail\"),Newtonsoft.Json.Linq.JValue).Value+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"Indirizzo: \"+Ctype(obj(\"value\")(i)(\"FullPrimaryAddress\"),Newtonsoft.Json.Linq.JValue).Value+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"Citt\u00e0: \"+obj(\"value\")(i)(\"DeliveryAddressCity\").ToString+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"Via: \"+ctype(obj(\"value\")(i)(\"DeliveryAddressStreet\"),Newtonsoft.Json.Linq.JValue).Value+vbcr\r\n  form.findcontrol(\"Editor1\").text+=\"Provincia:\"+ctype(obj(\"value\")(i)(\"AddressCounty\"),Newtonsoft.Json.Linq.JValue).Value+vbcr+vbcr\r\nNext<\/pre>\n<p>Come si pu\u00f2 notare, le parti di autenticazione e interrogazione sono costituite da pochissime righe, e, all&#8217;atto pratico, risultano molto efficienti. La parte pi\u00f9 complessa \u00e8 l&#8217;elaborazione del risultato, che risulta estremamente semplificato dalla libreria Newtonsoft.Json la quale consente di accedere all&#8217;array dei records (contenuto in&nbsp;<strong>obj(&#8220;value&#8221;)<\/strong>) e di estrarne i vari campi, che sono rappresentate da propriet\u00e0 degli oggetti contenuti nei vari elementi dell&#8217;array.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tramite uno script \u00e8 possibile importare dati da Microsoft Dynamics 365 utilizzando il protocollo oData e autenticandosi tramite il protocollo oAuth2. Queste tecnologie rappresentano lo stato dell&#8217;arte per quanto riguarda rispettivamente l&#8217;accesso ai dati RESTful e l&#8217;autenticazione a servizi in Cloud, e l&#8217;esempio sotto riportato \u00e8 quindi particolarmente importante costituendo un punto di partenza dal&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"ngg_post_thumbnail":0,"footnotes":""},"categories":[65],"tags":[81],"acf":[],"_links":{"self":[{"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/posts\/25310"}],"collection":[{"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/comments?post=25310"}],"version-history":[{"count":0,"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/posts\/25310\/revisions"}],"wp:attachment":[{"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/media?parent=25310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/categories?post=25310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/help.qualiware.it\/qw-help\/wp-json\/wp\/v2\/tags?post=25310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}