[{"data":1,"prerenderedAt":2764},["Reactive",2],{"navigation":3,"/posts/sqlclient-active-directory-authent":204,"/posts/sqlclient-active-directory-authent-surround":2734},[4,192,200],{"title":5,"_path":6,"children":7,"icon":191},"Blog","/posts",[8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188],{"title":9,"_path":10},"Testing your API with REST Client","/posts/testing-your-api-with-rest-client",{"title":12,"_path":13},"HTML templating in Xamarin","/posts/html-templating-in-xamarin",{"title":15,"_path":16},"Goodbye Azure Portal, Welcome Azure CLI","/posts/welcome-azure-cli",{"title":18,"_path":19},"Coming across Gitpod","/posts/gitpod",{"title":21,"_path":22},"Handle token retrieval while querying an API","/posts/delegating-handler",{"title":24,"_path":25},"Clean up your local git branches.","/posts/cleaning-git-branches",{"title":27,"_path":28},"Automate configuration of Teams Tab SSO with PowerShell.","/posts/teams-sso-powershell",{"title":30,"_path":31},"How to do a technology watch? - Part 1","/posts/technology-watch-part1",{"title":33,"_path":34},"How to do a technology watch? - Part 2","/posts/technology-watch-part2",{"title":36,"_path":37},"You almost no longer need Key Vault references for Azure Functions.","/posts/azure-functions-custom-configuration",{"title":39,"_path":40},"How to do a technology watch? - Part 3","/posts/technology-watch-part3",{"title":42,"_path":43},"Forget DevOps, the future is already here!","/posts/devops-future",{"title":45,"_path":46},"Week 9, 2021 - Tips I learned this week","/posts/w09-2021-tips-learned-this-week",{"title":48,"_path":49},"Week 12, 2021 - Tips I learned this week","/posts/w12-2021-tips-learned-this-week",{"title":51,"_path":52},"Week 14, 2021 - Tips I learned this week","/posts/w14-2021-tips-learned-this-week",{"title":54,"_path":55},"Once upon a time in .NET","/posts/once-upon-a-time-in-dotnet",{"title":57,"_path":58},"Install your applications with winget","/posts/winget-import",{"title":60,"_path":61},"Customize your applications when installing them with winget","/posts/winget-override",{"title":63,"_path":64},"Week 22, 2021 - Tips I learned this week","/posts/w22-2021-tips-learned-this-week",{"title":66,"_path":67},"How to connect to an Azure SQL Database from C# using Azure AD","/posts/sqlclient-active-directory-authent",{"title":69,"_path":70},"Producing packages for Windows Package Manager","/posts/wingetcreate",{"title":72,"_path":73},"4 tips about GitHub Actions environment variables and contexts","/posts/github-actions-var-and-context",{"title":75,"_path":76},"AzureWebJobsStorage, the secret you don't need in your Function App.","/posts/azure-functions-without-azurewebjobsstorage",{"title":78,"_path":79},"ASP.NET Core - Lost in configuration","/posts/lost-in-configuration",{"title":81,"_path":82},"Week 39, 2021 - Tips I learned this week","/posts/w39-2021-tips-learned-this-week",{"title":84,"_path":85},"Week 41, 2021 - Tips I learned this week","/posts/w41-2021-tips-learned-this-week",{"title":87,"_path":88},"Migrating and open-sourcing my blog","/posts/migrating-blog",{"title":90,"_path":91},"Week 45, 2021 - Tips I learned this week","/posts/w45-2021-tips-learned-this-week",{"title":93,"_path":94},"Organize your GitHub stars with Astral","/posts/astral",{"title":96,"_path":97},"Pulumi with an Azure Blob Storage backend","/posts/pulumi-azure-backend",{"title":99,"_path":100},"IaC Hot Reload with Pulumi Watch","/posts/pulumi-watch",{"title":102,"_path":103},"Week 2, 2022 - Tips I learned this week","/posts/w02-2022-tips-learned-this-week",{"title":105,"_path":106},"Week 3, 2022 - Tips I learned this week","/posts/w03-2022-tips-learned-this-week",{"title":108,"_path":109},"Week 5, 2022 - Tips I learned this week","/posts/w05-2022-tips-learned-this-week",{"title":111,"_path":112},"How to provision an Azure SQL Database with Active Directory authentication","/posts/sqldatabase-active-directory-authent",{"title":114,"_path":115},"Why will I choose Pulumi over Terraform for my next project?","/posts/pulumi-vs-terraform",{"title":117,"_path":118},"Week 19, 2022 - Tips I learned this week","/posts/w19-2022-tips-learned-this-week",{"title":120,"_path":121},"Week 20, 2022 - Tips I learned this week","/posts/w20-2022-tips-learned-this-week",{"title":123,"_path":124},"Keeping secrets secure when using API Clients","/posts/http-clients-secrets",{"title":126,"_path":127},"What made me want to be a developer?","/posts/be-a-developer",{"title":129,"_path":130},"What can we do when stuck with a programming problem?","/posts/get-unstuck",{"title":132,"_path":133},"How did I automate the setup of my developer Windows laptop?","/posts/automate-developer-machine",{"title":135,"_path":136},"Discussion about API clients","/posts/http-clients",{"title":138,"_path":139},"Week 46, 2022 - Tips I learned this week","/posts/w46-2022-tips-learned-this-week",{"title":141,"_path":142},"When Pulumi met Nuke: a .NET love story","/posts/when-pulumi-met-nuke",{"title":144,"_path":145},"A year of learning and sharing - Dev Retro 2022","/posts/2022-retro",{"title":147,"_path":148},"Perform Dynamic Execution of an npm Package","/posts/pnpm-dlx",{"title":150,"_path":151},"Manage multiple Node.js versions","/posts/pnpm-env",{"title":153,"_path":154},"Introducing the Vue.js CI/CD series","/posts/vuecicd-introduction",{"title":156,"_path":157},"Execute commands using your project dependencies","/posts/pnpm-exec",{"title":159,"_path":160},"Vue.js CI/CD: Continuous Integration","/posts/vuecicd-ci",{"title":162,"_path":163},"Who is using pnpm?","/posts/pnpm-who-is-using",{"title":165,"_path":166},"Create an Azure-Ready GitHub Repository using Pulumi","/posts/azure-ready-github-repository",{"title":168,"_path":169},"Deploying to Azure from Azure DevOps without secrets","/posts/ado-workload-identity-federation",{"title":171,"_path":172},"Effortlessly Configure GitHub Repositories for Azure Deployment via OIDC","/posts/scripting-azure-ready-github-repository",{"title":174,"_path":175},"Playing with the .NET 8 Web API template","/posts/playing-with-dotnet8",{"title":177,"_path":178},"Another year of sharing and learning - Dev Retro 2023","/posts/2023-retro",{"title":180,"_path":181},"Week 4, 2024 - Tips I learned this week","/posts/w04-2024-tips-learned-this-week",{"title":183,"_path":184},"Using dependency injection with Azure .NET SDK","/posts/azure-sdk-di",{"title":186,"_path":187},"Having Fun With IT Event Calendars","/posts/it-event-calendars",{"title":189,"_path":190},"Call your Azure AD B2C protected API with authenticated HTTP requests from your JetBrains IDE","/posts/http-clients-oauth2","i-heroicons-newspaper",{"title":193,"_path":194,"children":195,"icon":199},"Goodies","/goodies",[196],{"title":197,"_path":198},"My Git Cheat Sheet","/goodies/gitcheatsheet","i-heroicons-gift-solid",{"title":201,"_path":202,"icon":203},"About","/about","i-heroicons-user-circle-solid",{"_path":67,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":66,"description":208,"lead":209,"date":210,"image":211,"badge":213,"tags":215,"body":222,"_type":2729,"_id":2730,"_source":2731,"_file":2732,"_extension":2733},"posts",false,"","In Microsoft.Data.SqlClient v3.0.0, a new authentication mode Active Directory Default has been released. Let's see what this means when querying an Azure SQL Database from some C# code.","Talking about Active Directory Default authentication mode for SqlClient.","2021-06-22T00:00:00.000Z",{"src":212},"/images/cloud-azure_1.jpg",{"label":214},"Development",[216,217,218,219,220,221],"Azure Active Directory","Azure SQL Database","Azure SDK","Azure","Azure CLI","ASP.NET Core",{"type":223,"children":224,"toc":2718},"root",[225,250,275,280,287,308,461,473,478,503,508,514,519,524,539,551,762,801,806,819,853,932,948,954,959,966,980,1999,2004,2039,2044,2059,2065,2079,2092,2600,2605,2665,2677,2693,2699,2712],{"type":226,"tag":227,"props":228,"children":229},"element","p",{},[230,233,240,242,248],{"type":231,"value":232},"text","In ",{"type":226,"tag":234,"props":235,"children":237},"code",{"className":236},[],[238],{"type":231,"value":239},"Microsoft.Data.SqlClient",{"type":231,"value":241}," v3.0.0, a new authentication mode ",{"type":226,"tag":234,"props":243,"children":245},{"className":244},[],[246],{"type":231,"value":247},"Active Directory Default",{"type":231,"value":249}," has been released. Let's see what this means when querying an Azure SQL Database from some C# code.",{"type":226,"tag":251,"props":252,"children":254},"callout",{"icon":253},"i-heroicons-chat-bubble-left-20-solid",[255],{"type":226,"tag":227,"props":256,"children":257},{},[258,260,265,267,273],{"type":231,"value":259},"If you do not have heard about ",{"type":226,"tag":234,"props":261,"children":263},{"className":262},[],[264],{"type":231,"value":239},{"type":231,"value":266},", it is the new data provider for Microsoft SQL Server and Azure SQL Database which supports both .NET Framework and .NET Core and replace the old ",{"type":226,"tag":234,"props":268,"children":270},{"className":269},[],[271],{"type":231,"value":272},"System.Data.SqlClient",{"type":231,"value":274}," components.",{"type":226,"tag":227,"props":276,"children":277},{},[278],{"type":231,"value":279},"But first, let's talk about how we used to do that before.",{"type":226,"tag":281,"props":282,"children":284},"h2",{"id":283},"the-traditional-way-using-a-secret-connection-string",[285],{"type":231,"value":286},"The traditional way: using a secret connection string",{"type":226,"tag":227,"props":288,"children":289},{},[290,292,298,300,306],{"type":231,"value":291},"The ",{"type":226,"tag":234,"props":293,"children":295},{"className":294},[],[296],{"type":231,"value":297},"traditional way",{"type":231,"value":299}," to connect to an Azure SQL database from an application in C# is to provide to the ",{"type":226,"tag":234,"props":301,"children":303},{"className":302},[],[304],{"type":231,"value":305},"SqlConnection",{"type":231,"value":307}," constructor a connection string that contains a username and a password. The corresponding C# code is quite simple:",{"type":226,"tag":309,"props":310,"children":314},"pre",{"className":311,"code":312,"language":313,"meta":207,"style":207},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","var connectionString = \"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;User ID=globalSqlAdmin;Password=MySecretPassword;\");\n\nusing (var sqlConnection = new SqlConnection(connectionString));\nawait connection.OpenAsync();\n","csharp",[315],{"type":226,"tag":234,"props":316,"children":317},{"__ignoreMap":207},[318,368,378,431],{"type":226,"tag":319,"props":320,"children":323},"span",{"class":321,"line":322},"line",1,[324,330,335,341,346,352,357,363],{"type":226,"tag":319,"props":325,"children":327},{"style":326},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[328],{"type":231,"value":329},"var",{"type":226,"tag":319,"props":331,"children":332},{"style":326},[333],{"type":231,"value":334}," connectionString",{"type":226,"tag":319,"props":336,"children":338},{"style":337},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[339],{"type":231,"value":340}," =",{"type":226,"tag":319,"props":342,"children":343},{"style":337},[344],{"type":231,"value":345}," \"",{"type":226,"tag":319,"props":347,"children":349},{"style":348},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[350],{"type":231,"value":351},"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;User ID=globalSqlAdmin;Password=MySecretPassword;",{"type":226,"tag":319,"props":353,"children":354},{"style":337},[355],{"type":231,"value":356},"\"",{"type":226,"tag":319,"props":358,"children":360},{"style":359},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[361],{"type":231,"value":362},")",{"type":226,"tag":319,"props":364,"children":365},{"style":337},[366],{"type":231,"value":367},";\n",{"type":226,"tag":319,"props":369,"children":371},{"class":321,"line":370},2,[372],{"type":226,"tag":319,"props":373,"children":375},{"emptyLinePlaceholder":374},true,[376],{"type":231,"value":377},"\n",{"type":226,"tag":319,"props":379,"children":381},{"class":321,"line":380},3,[382,388,393,397,402,406,411,416,421,426],{"type":226,"tag":319,"props":383,"children":385},{"style":384},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[386],{"type":231,"value":387},"using",{"type":226,"tag":319,"props":389,"children":390},{"style":337},[391],{"type":231,"value":392}," (",{"type":226,"tag":319,"props":394,"children":395},{"style":326},[396],{"type":231,"value":329},{"type":226,"tag":319,"props":398,"children":399},{"style":326},[400],{"type":231,"value":401}," sqlConnection",{"type":226,"tag":319,"props":403,"children":404},{"style":337},[405],{"type":231,"value":340},{"type":226,"tag":319,"props":407,"children":408},{"style":337},[409],{"type":231,"value":410}," new",{"type":226,"tag":319,"props":412,"children":413},{"style":326},[414],{"type":231,"value":415}," SqlConnection",{"type":226,"tag":319,"props":417,"children":418},{"style":337},[419],{"type":231,"value":420},"(",{"type":226,"tag":319,"props":422,"children":423},{"style":359},[424],{"type":231,"value":425},"connectionString",{"type":226,"tag":319,"props":427,"children":428},{"style":337},[429],{"type":231,"value":430},"));\n",{"type":226,"tag":319,"props":432,"children":434},{"class":321,"line":433},4,[435,440,445,450,456],{"type":226,"tag":319,"props":436,"children":437},{"style":337},[438],{"type":231,"value":439},"await",{"type":226,"tag":319,"props":441,"children":442},{"style":359},[443],{"type":231,"value":444}," connection",{"type":226,"tag":319,"props":446,"children":447},{"style":337},[448],{"type":231,"value":449},".",{"type":226,"tag":319,"props":451,"children":453},{"style":452},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[454],{"type":231,"value":455},"OpenAsync",{"type":226,"tag":319,"props":457,"children":458},{"style":337},[459],{"type":231,"value":460},"();\n",{"type":226,"tag":227,"props":462,"children":463},{},[464,466,472],{"type":231,"value":465},"In that case, the connection string is a secret we must secure and not just by putting it in some configuration location everyone can have access to, but by storing it in a secured place like ",{"type":226,"tag":234,"props":467,"children":469},{"className":468},[],[470],{"type":231,"value":471},"Azure Key Vault",{"type":231,"value":449},{"type":226,"tag":227,"props":474,"children":475},{},[476],{"type":231,"value":477},"However, even if you secure it appropriately, using a connection string with a username/password in it has some disadvantages:",{"type":226,"tag":479,"props":480,"children":481},"ul",{},[482,488,493,498],{"type":226,"tag":483,"props":484,"children":485},"li",{},[486],{"type":231,"value":487},"you need to handle who has access to it (so who has access to the key vault)",{"type":226,"tag":483,"props":489,"children":490},{},[491],{"type":231,"value":492},"every application or every developer could potentially use the same connection string so auditing is not very convenient (for instance identifying in the database logs which user has run a specific transaction)",{"type":226,"tag":483,"props":494,"children":495},{},[496],{"type":231,"value":497},"you only control who has access to the connection string in the key vault, not what people do with it (share it by email, store it on their local computer, ...) so not who can access the database",{"type":226,"tag":483,"props":499,"children":500},{},[501],{"type":231,"value":502},"you need to handle the rotation of the secret, in other words, change the username/password regularly (because you can revoke the access to someone to the database, if he had access to the connection string at some point in time it is not a secret for him anymore)",{"type":226,"tag":227,"props":504,"children":505},{},[506],{"type":231,"value":507},"For all these reasons, using a secret connection string to connect to an Azure SQL Database is not the right approach.",{"type":226,"tag":281,"props":509,"children":511},{"id":510},"the-new-way-using-azure-active-directory-authentication",[512],{"type":231,"value":513},"The new way: using Azure Active Directory Authentication",{"type":226,"tag":227,"props":515,"children":516},{},[517],{"type":231,"value":518},"Instead of using a secret connection string to connect to a database, the idea is to use the Azure Active Directory authentication mechanism. Azure Active Directory is the location that contains all the identities of your users and your applications in your company. So you can manage directly which identity (user or application) have access to a database.",{"type":226,"tag":227,"props":520,"children":521},{},[522],{"type":231,"value":523},"Applications or users that want to query a database will authenticate against Azure AD to retrieve an access token that will allow them to access the database using a connection string without any username nor password.",{"type":226,"tag":227,"props":525,"children":526},{},[527,529,538],{"type":231,"value":528},"If you want to know more about the advantages of using Azure AD authentication for connecting to an Azure SQL Database you can have a look in the ",{"type":226,"tag":530,"props":531,"children":535},"a",{"href":532,"rel":533},"https://docs.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-overview",[534],"nofollow",[536],{"type":231,"value":537},"official documentation",{"type":231,"value":449},{"type":226,"tag":227,"props":540,"children":541},{},[542,544,549],{"type":231,"value":543},"In the code we can remove the user id and password from the connection string but we have to retrieve an Azure AD access token and pass it to the ",{"type":226,"tag":234,"props":545,"children":547},{"className":546},[],[548],{"type":231,"value":305},{"type":231,"value":550}," instance:",{"type":226,"tag":309,"props":552,"children":554},{"className":311,"code":553,"language":313,"meta":207,"style":207},"var accessToken = await new DefaultAzureCredential().GetTokenAsync(new TokenRequestContext(new string[] { \"https://database.windows.net//.default\" }));\nusing var connection = new SqlConnection(\"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;\")\n{\n    AccessToken = accessToken.Token\n};\nawait connection.OpenAsync();\n",[555],{"type":226,"tag":234,"props":556,"children":557},{"__ignoreMap":207},[558,645,695,703,729,738],{"type":226,"tag":319,"props":559,"children":560},{"class":321,"line":322},[561,565,570,574,579,583,588,593,598,603,608,612,617,622,627,631,636,640],{"type":226,"tag":319,"props":562,"children":563},{"style":326},[564],{"type":231,"value":329},{"type":226,"tag":319,"props":566,"children":567},{"style":326},[568],{"type":231,"value":569}," accessToken",{"type":226,"tag":319,"props":571,"children":572},{"style":337},[573],{"type":231,"value":340},{"type":226,"tag":319,"props":575,"children":576},{"style":337},[577],{"type":231,"value":578}," await",{"type":226,"tag":319,"props":580,"children":581},{"style":337},[582],{"type":231,"value":410},{"type":226,"tag":319,"props":584,"children":585},{"style":326},[586],{"type":231,"value":587}," DefaultAzureCredential",{"type":226,"tag":319,"props":589,"children":590},{"style":337},[591],{"type":231,"value":592},"().",{"type":226,"tag":319,"props":594,"children":595},{"style":452},[596],{"type":231,"value":597},"GetTokenAsync",{"type":226,"tag":319,"props":599,"children":600},{"style":337},[601],{"type":231,"value":602},"(new",{"type":226,"tag":319,"props":604,"children":605},{"style":326},[606],{"type":231,"value":607}," TokenRequestContext",{"type":226,"tag":319,"props":609,"children":610},{"style":337},[611],{"type":231,"value":602},{"type":226,"tag":319,"props":613,"children":614},{"style":337},[615],{"type":231,"value":616}," string",{"type":226,"tag":319,"props":618,"children":619},{"style":337},[620],{"type":231,"value":621},"[]",{"type":226,"tag":319,"props":623,"children":624},{"style":337},[625],{"type":231,"value":626}," {",{"type":226,"tag":319,"props":628,"children":629},{"style":337},[630],{"type":231,"value":345},{"type":226,"tag":319,"props":632,"children":633},{"style":348},[634],{"type":231,"value":635},"https://database.windows.net//.default",{"type":226,"tag":319,"props":637,"children":638},{"style":337},[639],{"type":231,"value":356},{"type":226,"tag":319,"props":641,"children":642},{"style":337},[643],{"type":231,"value":644}," }));\n",{"type":226,"tag":319,"props":646,"children":647},{"class":321,"line":370},[648,652,657,661,665,669,673,677,681,686,690],{"type":226,"tag":319,"props":649,"children":650},{"style":384},[651],{"type":231,"value":387},{"type":226,"tag":319,"props":653,"children":654},{"style":326},[655],{"type":231,"value":656}," var",{"type":226,"tag":319,"props":658,"children":659},{"style":326},[660],{"type":231,"value":444},{"type":226,"tag":319,"props":662,"children":663},{"style":337},[664],{"type":231,"value":340},{"type":226,"tag":319,"props":666,"children":667},{"style":337},[668],{"type":231,"value":410},{"type":226,"tag":319,"props":670,"children":671},{"style":326},[672],{"type":231,"value":415},{"type":226,"tag":319,"props":674,"children":675},{"style":337},[676],{"type":231,"value":420},{"type":226,"tag":319,"props":678,"children":679},{"style":337},[680],{"type":231,"value":356},{"type":226,"tag":319,"props":682,"children":683},{"style":348},[684],{"type":231,"value":685},"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;",{"type":226,"tag":319,"props":687,"children":688},{"style":337},[689],{"type":231,"value":356},{"type":226,"tag":319,"props":691,"children":692},{"style":337},[693],{"type":231,"value":694},")\n",{"type":226,"tag":319,"props":696,"children":697},{"class":321,"line":380},[698],{"type":226,"tag":319,"props":699,"children":700},{"style":337},[701],{"type":231,"value":702},"{\n",{"type":226,"tag":319,"props":704,"children":705},{"class":321,"line":433},[706,711,716,720,724],{"type":226,"tag":319,"props":707,"children":708},{"style":359},[709],{"type":231,"value":710},"    AccessToken ",{"type":226,"tag":319,"props":712,"children":713},{"style":337},[714],{"type":231,"value":715},"=",{"type":226,"tag":319,"props":717,"children":718},{"style":359},[719],{"type":231,"value":569},{"type":226,"tag":319,"props":721,"children":722},{"style":337},[723],{"type":231,"value":449},{"type":226,"tag":319,"props":725,"children":726},{"style":359},[727],{"type":231,"value":728},"Token\n",{"type":226,"tag":319,"props":730,"children":732},{"class":321,"line":731},5,[733],{"type":226,"tag":319,"props":734,"children":735},{"style":337},[736],{"type":231,"value":737},"};\n",{"type":226,"tag":319,"props":739,"children":741},{"class":321,"line":740},6,[742,746,750,754,758],{"type":226,"tag":319,"props":743,"children":744},{"style":337},[745],{"type":231,"value":439},{"type":226,"tag":319,"props":747,"children":748},{"style":359},[749],{"type":231,"value":444},{"type":226,"tag":319,"props":751,"children":752},{"style":337},[753],{"type":231,"value":449},{"type":226,"tag":319,"props":755,"children":756},{"style":452},[757],{"type":231,"value":455},{"type":226,"tag":319,"props":759,"children":760},{"style":337},[761],{"type":231,"value":460},{"type":226,"tag":227,"props":763,"children":764},{},[765,767,774,776,782,784,791,793,799],{"type":231,"value":766},"The code is using the ",{"type":226,"tag":530,"props":768,"children":771},{"href":769,"rel":770},"https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme",[534],[772],{"type":231,"value":773},"Azure Identity library",{"type":231,"value":775}," which as the documentation says \"",{"type":226,"tag":777,"props":778,"children":779},"em",{},[780],{"type":231,"value":781},"provides Azure Active Directory token authentication support across the Azure SDK",{"type":231,"value":783},"\". It is the recommended way to get an Azure token although you may have seen code that uses another library ",{"type":226,"tag":530,"props":785,"children":788},{"href":786,"rel":787},"https://www.nuget.org/packages/Microsoft.Azure.Services.AppAuthentication",[534],[789],{"type":231,"value":790},"Microsoft.Azure.Services.AppAuthentication",{"type":231,"value":792}," to do the same thing. The class ",{"type":226,"tag":234,"props":794,"children":796},{"className":795},[],[797],{"type":231,"value":798},"DefaultAzureCredential",{"type":231,"value":800}," from Azure Identity library combines multiple authentication mechanisms (like Managed Identities, Visual Studio, Azure CLI ...) that will be tried in order to retrieve a token so it is a practical class that can handle most of the scenarios.",{"type":226,"tag":227,"props":802,"children":803},{},[804],{"type":231,"value":805},"Therefore, provided that you have granted access to your database to the user you are using locally (in Visual Studio, in vs code, or in Azure CLI) and to the managed identity of your application in Azure (App Service or Azure Function for instance) the same code will work both locally and in Azure.",{"type":226,"tag":281,"props":807,"children":809},{"id":808},"here-comes-active-directory-default-authentication-mode",[810,812,817],{"type":231,"value":811},"Here comes ",{"type":226,"tag":234,"props":813,"children":815},{"className":814},[],[816],{"type":231,"value":247},{"type":231,"value":818}," authentication mode",{"type":226,"tag":227,"props":820,"children":821},{},[822,824,829,831,836,838,844,846,851],{"type":231,"value":823},"We have seen that using Azure Active Directory Authentication was a better solution than using a connection string with secrets in it to connect to a database. However, it involves manually retrieving an Azure AD token which makes the code a bit more complex to read. That is exactly why ",{"type":226,"tag":234,"props":825,"children":827},{"className":826},[],[828],{"type":231,"value":247},{"type":231,"value":830}," new authentication mode was introduced in ",{"type":226,"tag":234,"props":832,"children":834},{"className":833},[],[835],{"type":231,"value":239},{"type":231,"value":837}," v3.0.0. Under the hood, ",{"type":226,"tag":234,"props":839,"children":841},{"className":840},[],[842],{"type":231,"value":843},"SqlClient",{"type":231,"value":845}," does the same thing that we were showing previously so we don't have to do it ourselves: just specifying the authentication mode to ",{"type":226,"tag":234,"props":847,"children":849},{"className":848},[],[850],{"type":231,"value":247},{"type":231,"value":852}," in the connection string is enough to make it work.",{"type":226,"tag":309,"props":854,"children":856},{"className":311,"code":855,"language":313,"meta":207,"style":207},"using var connection = new SqlConnection(\"Server=server-testingmsi6499.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi6499;\");\nawait connection.OpenAsync();\n",[857],{"type":226,"tag":234,"props":858,"children":859},{"__ignoreMap":207},[860,909],{"type":226,"tag":319,"props":861,"children":862},{"class":321,"line":322},[863,867,871,875,879,883,887,891,895,900,904],{"type":226,"tag":319,"props":864,"children":865},{"style":384},[866],{"type":231,"value":387},{"type":226,"tag":319,"props":868,"children":869},{"style":326},[870],{"type":231,"value":656},{"type":226,"tag":319,"props":872,"children":873},{"style":326},[874],{"type":231,"value":444},{"type":226,"tag":319,"props":876,"children":877},{"style":337},[878],{"type":231,"value":340},{"type":226,"tag":319,"props":880,"children":881},{"style":337},[882],{"type":231,"value":410},{"type":226,"tag":319,"props":884,"children":885},{"style":326},[886],{"type":231,"value":415},{"type":226,"tag":319,"props":888,"children":889},{"style":337},[890],{"type":231,"value":420},{"type":226,"tag":319,"props":892,"children":893},{"style":337},[894],{"type":231,"value":356},{"type":226,"tag":319,"props":896,"children":897},{"style":348},[898],{"type":231,"value":899},"Server=server-testingmsi6499.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi6499;",{"type":226,"tag":319,"props":901,"children":902},{"style":337},[903],{"type":231,"value":356},{"type":226,"tag":319,"props":905,"children":906},{"style":337},[907],{"type":231,"value":908},");\n",{"type":226,"tag":319,"props":910,"children":911},{"class":321,"line":370},[912,916,920,924,928],{"type":226,"tag":319,"props":913,"children":914},{"style":337},[915],{"type":231,"value":439},{"type":226,"tag":319,"props":917,"children":918},{"style":359},[919],{"type":231,"value":444},{"type":226,"tag":319,"props":921,"children":922},{"style":337},[923],{"type":231,"value":449},{"type":226,"tag":319,"props":925,"children":926},{"style":452},[927],{"type":231,"value":455},{"type":226,"tag":319,"props":929,"children":930},{"style":337},[931],{"type":231,"value":460},{"type":226,"tag":251,"props":933,"children":934},{"icon":253},[935],{"type":226,"tag":227,"props":936,"children":937},{},[938,940,947],{"type":231,"value":939},"There are other Azure Active Directory authentication methods available, you can find them in the documentation ",{"type":226,"tag":530,"props":941,"children":944},{"href":942,"rel":943},"https://docs.microsoft.com/en-us/sql/connect/ado-net/sql/azure-active-directory-authentication?view=sql-server-ver15#using-active-directory-password-authentication",[534],[945],{"type":231,"value":946},"here",{"type":231,"value":449},{"type":226,"tag":281,"props":949,"children":951},{"id":950},"a-complete-example",[952],{"type":231,"value":953},"A complete example",{"type":226,"tag":227,"props":955,"children":956},{},[957],{"type":231,"value":958},"Enough theory, what if you want to quickly test this by yourself?",{"type":226,"tag":960,"props":961,"children":963},"h3",{"id":962},"a-bit-of-azure-cli-to-initialize-the-database",[964],{"type":231,"value":965},"A bit of Azure CLI to initialize the database",{"type":226,"tag":227,"props":967,"children":968},{},[969,971,978],{"type":231,"value":970},"I took an ",{"type":226,"tag":530,"props":972,"children":975},{"href":973,"rel":974},"https://docs.microsoft.com/en-us/azure/azure-sql/database/scripts/create-and-configure-database-cli",[534],[976],{"type":231,"value":977},"Azure CLI sample script",{"type":231,"value":979}," from Microsoft and modify it a little to configure a database with all that is necessary to use Azure Active Directory to connect my user to it.",{"type":226,"tag":309,"props":981,"children":985},{"className":982,"code":983,"language":984,"meta":207,"style":207},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#!/bin/bash\nlocation=\"West Europe\" # to change with your preferred location\nrandomIdentifier=testingmsi${RANDOM:0:5}\n\nresourceGroup=\"resource-$randomIdentifier\"\nserver=\"server-$randomIdentifier\"\ndatabase=\"database-$randomIdentifier\"\n\nlogin=\"globalSqlAdmin\"\npassword=\"P@ssw0rdToChange!\" # to change to have a more secured password\n\n# Retrieve your public IP.\n# Replace by your local machine IP if you are executing this script from cloud shell.\nstartIP=$(dig +short myip.opendns.com @resolver1.opendns.com)\nendIP=$startIP\n\n# Retrieve your current logged-in user to be used as SQL server admin. \n# Change with another user id if you want another user to be an admin.\nazureaduser=$(az ad signed-in-user show --query \"objectId\" -o tsv)\n\necho \"Creating $resourceGroup...\"\naz group create --name $resourceGroup --location \"$location\"\n\necho \"Creating $server in $location...\"\naz sql server create --name $server --resource-group $resourceGroup --location \"$location\" --admin-user $login --admin-password $password\n\necho \"Configuring firewall...\"\naz sql server firewall-rule create --resource-group $resourceGroup --server $server -n AllowYourIp --start-ip-address $startIP --end-ip-address $endIP\n\necho \"Creating $database on $server...\"\naz sql db create --resource-group $resourceGroup --server $server --name $database --sample-name AdventureWorksLT --service-objective Basic --zone-redundant false\n\necho \"Creating AD admin in sql server...\"\naz sql server ad-admin create --resource-group $resourceGroup --server-name $server --display-name ADMIN --object-id $azureaduser\n\necho \"Database connection string to use: \\\"Server=$server.database.windows.net; Authentication=Active Directory Default; Database=$database;\\\"\"\n","bash",[986],{"type":226,"tag":234,"props":987,"children":988},{"__ignoreMap":207},[989,998,1028,1079,1086,1117,1146,1176,1184,1210,1241,1249,1258,1267,1305,1323,1331,1340,1349,1414,1422,1454,1500,1508,1546,1622,1630,1651,1724,1732,1770,1847,1855,1876,1938,1946],{"type":226,"tag":319,"props":990,"children":991},{"class":321,"line":322},[992],{"type":226,"tag":319,"props":993,"children":995},{"style":994},"--shiki-light:#90A4AE;--shiki-default:#546E7A;--shiki-dark:#676E95;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[996],{"type":231,"value":997},"#!/bin/bash\n",{"type":226,"tag":319,"props":999,"children":1000},{"class":321,"line":370},[1001,1006,1010,1014,1019,1023],{"type":226,"tag":319,"props":1002,"children":1003},{"style":359},[1004],{"type":231,"value":1005},"location",{"type":226,"tag":319,"props":1007,"children":1008},{"style":337},[1009],{"type":231,"value":715},{"type":226,"tag":319,"props":1011,"children":1012},{"style":337},[1013],{"type":231,"value":356},{"type":226,"tag":319,"props":1015,"children":1016},{"style":348},[1017],{"type":231,"value":1018},"West Europe",{"type":226,"tag":319,"props":1020,"children":1021},{"style":337},[1022],{"type":231,"value":356},{"type":226,"tag":319,"props":1024,"children":1025},{"style":994},[1026],{"type":231,"value":1027}," # to change with your preferred location\n",{"type":226,"tag":319,"props":1029,"children":1030},{"class":321,"line":380},[1031,1036,1040,1045,1050,1055,1060,1065,1069,1074],{"type":226,"tag":319,"props":1032,"children":1033},{"style":359},[1034],{"type":231,"value":1035},"randomIdentifier",{"type":226,"tag":319,"props":1037,"children":1038},{"style":337},[1039],{"type":231,"value":715},{"type":226,"tag":319,"props":1041,"children":1042},{"style":348},[1043],{"type":231,"value":1044},"testingmsi",{"type":226,"tag":319,"props":1046,"children":1047},{"style":337},[1048],{"type":231,"value":1049},"${",{"type":226,"tag":319,"props":1051,"children":1052},{"style":359},[1053],{"type":231,"value":1054},"RANDOM",{"type":226,"tag":319,"props":1056,"children":1057},{"style":337},[1058],{"type":231,"value":1059},":",{"type":226,"tag":319,"props":1061,"children":1062},{"style":359},[1063],{"type":231,"value":1064},"0",{"type":226,"tag":319,"props":1066,"children":1067},{"style":337},[1068],{"type":231,"value":1059},{"type":226,"tag":319,"props":1070,"children":1071},{"style":359},[1072],{"type":231,"value":1073},"5",{"type":226,"tag":319,"props":1075,"children":1076},{"style":337},[1077],{"type":231,"value":1078},"}\n",{"type":226,"tag":319,"props":1080,"children":1081},{"class":321,"line":433},[1082],{"type":226,"tag":319,"props":1083,"children":1084},{"emptyLinePlaceholder":374},[1085],{"type":231,"value":377},{"type":226,"tag":319,"props":1087,"children":1088},{"class":321,"line":731},[1089,1094,1098,1102,1107,1112],{"type":226,"tag":319,"props":1090,"children":1091},{"style":359},[1092],{"type":231,"value":1093},"resourceGroup",{"type":226,"tag":319,"props":1095,"children":1096},{"style":337},[1097],{"type":231,"value":715},{"type":226,"tag":319,"props":1099,"children":1100},{"style":337},[1101],{"type":231,"value":356},{"type":226,"tag":319,"props":1103,"children":1104},{"style":348},[1105],{"type":231,"value":1106},"resource-",{"type":226,"tag":319,"props":1108,"children":1109},{"style":359},[1110],{"type":231,"value":1111},"$randomIdentifier",{"type":226,"tag":319,"props":1113,"children":1114},{"style":337},[1115],{"type":231,"value":1116},"\"\n",{"type":226,"tag":319,"props":1118,"children":1119},{"class":321,"line":740},[1120,1125,1129,1133,1138,1142],{"type":226,"tag":319,"props":1121,"children":1122},{"style":359},[1123],{"type":231,"value":1124},"server",{"type":226,"tag":319,"props":1126,"children":1127},{"style":337},[1128],{"type":231,"value":715},{"type":226,"tag":319,"props":1130,"children":1131},{"style":337},[1132],{"type":231,"value":356},{"type":226,"tag":319,"props":1134,"children":1135},{"style":348},[1136],{"type":231,"value":1137},"server-",{"type":226,"tag":319,"props":1139,"children":1140},{"style":359},[1141],{"type":231,"value":1111},{"type":226,"tag":319,"props":1143,"children":1144},{"style":337},[1145],{"type":231,"value":1116},{"type":226,"tag":319,"props":1147,"children":1149},{"class":321,"line":1148},7,[1150,1155,1159,1163,1168,1172],{"type":226,"tag":319,"props":1151,"children":1152},{"style":359},[1153],{"type":231,"value":1154},"database",{"type":226,"tag":319,"props":1156,"children":1157},{"style":337},[1158],{"type":231,"value":715},{"type":226,"tag":319,"props":1160,"children":1161},{"style":337},[1162],{"type":231,"value":356},{"type":226,"tag":319,"props":1164,"children":1165},{"style":348},[1166],{"type":231,"value":1167},"database-",{"type":226,"tag":319,"props":1169,"children":1170},{"style":359},[1171],{"type":231,"value":1111},{"type":226,"tag":319,"props":1173,"children":1174},{"style":337},[1175],{"type":231,"value":1116},{"type":226,"tag":319,"props":1177,"children":1179},{"class":321,"line":1178},8,[1180],{"type":226,"tag":319,"props":1181,"children":1182},{"emptyLinePlaceholder":374},[1183],{"type":231,"value":377},{"type":226,"tag":319,"props":1185,"children":1187},{"class":321,"line":1186},9,[1188,1193,1197,1201,1206],{"type":226,"tag":319,"props":1189,"children":1190},{"style":359},[1191],{"type":231,"value":1192},"login",{"type":226,"tag":319,"props":1194,"children":1195},{"style":337},[1196],{"type":231,"value":715},{"type":226,"tag":319,"props":1198,"children":1199},{"style":337},[1200],{"type":231,"value":356},{"type":226,"tag":319,"props":1202,"children":1203},{"style":348},[1204],{"type":231,"value":1205},"globalSqlAdmin",{"type":226,"tag":319,"props":1207,"children":1208},{"style":337},[1209],{"type":231,"value":1116},{"type":226,"tag":319,"props":1211,"children":1213},{"class":321,"line":1212},10,[1214,1219,1223,1227,1232,1236],{"type":226,"tag":319,"props":1215,"children":1216},{"style":359},[1217],{"type":231,"value":1218},"password",{"type":226,"tag":319,"props":1220,"children":1221},{"style":337},[1222],{"type":231,"value":715},{"type":226,"tag":319,"props":1224,"children":1225},{"style":337},[1226],{"type":231,"value":356},{"type":226,"tag":319,"props":1228,"children":1229},{"style":348},[1230],{"type":231,"value":1231},"P@ssw0rdToChange!",{"type":226,"tag":319,"props":1233,"children":1234},{"style":337},[1235],{"type":231,"value":356},{"type":226,"tag":319,"props":1237,"children":1238},{"style":994},[1239],{"type":231,"value":1240}," # to change to have a more secured password\n",{"type":226,"tag":319,"props":1242,"children":1244},{"class":321,"line":1243},11,[1245],{"type":226,"tag":319,"props":1246,"children":1247},{"emptyLinePlaceholder":374},[1248],{"type":231,"value":377},{"type":226,"tag":319,"props":1250,"children":1252},{"class":321,"line":1251},12,[1253],{"type":226,"tag":319,"props":1254,"children":1255},{"style":994},[1256],{"type":231,"value":1257},"# Retrieve your public IP.\n",{"type":226,"tag":319,"props":1259,"children":1261},{"class":321,"line":1260},13,[1262],{"type":226,"tag":319,"props":1263,"children":1264},{"style":994},[1265],{"type":231,"value":1266},"# Replace by your local machine IP if you are executing this script from cloud shell.\n",{"type":226,"tag":319,"props":1268,"children":1270},{"class":321,"line":1269},14,[1271,1276,1281,1286,1291,1296,1301],{"type":226,"tag":319,"props":1272,"children":1273},{"style":359},[1274],{"type":231,"value":1275},"startIP",{"type":226,"tag":319,"props":1277,"children":1278},{"style":337},[1279],{"type":231,"value":1280},"=$(",{"type":226,"tag":319,"props":1282,"children":1283},{"style":326},[1284],{"type":231,"value":1285},"dig",{"type":226,"tag":319,"props":1287,"children":1288},{"style":348},[1289],{"type":231,"value":1290}," +short",{"type":226,"tag":319,"props":1292,"children":1293},{"style":348},[1294],{"type":231,"value":1295}," myip.opendns.com",{"type":226,"tag":319,"props":1297,"children":1298},{"style":348},[1299],{"type":231,"value":1300}," @resolver1.opendns.com",{"type":226,"tag":319,"props":1302,"children":1303},{"style":337},[1304],{"type":231,"value":694},{"type":226,"tag":319,"props":1306,"children":1308},{"class":321,"line":1307},15,[1309,1314,1318],{"type":226,"tag":319,"props":1310,"children":1311},{"style":359},[1312],{"type":231,"value":1313},"endIP",{"type":226,"tag":319,"props":1315,"children":1316},{"style":337},[1317],{"type":231,"value":715},{"type":226,"tag":319,"props":1319,"children":1320},{"style":359},[1321],{"type":231,"value":1322},"$startIP\n",{"type":226,"tag":319,"props":1324,"children":1326},{"class":321,"line":1325},16,[1327],{"type":226,"tag":319,"props":1328,"children":1329},{"emptyLinePlaceholder":374},[1330],{"type":231,"value":377},{"type":226,"tag":319,"props":1332,"children":1334},{"class":321,"line":1333},17,[1335],{"type":226,"tag":319,"props":1336,"children":1337},{"style":994},[1338],{"type":231,"value":1339},"# Retrieve your current logged-in user to be used as SQL server admin. \n",{"type":226,"tag":319,"props":1341,"children":1343},{"class":321,"line":1342},18,[1344],{"type":226,"tag":319,"props":1345,"children":1346},{"style":994},[1347],{"type":231,"value":1348},"# Change with another user id if you want another user to be an admin.\n",{"type":226,"tag":319,"props":1350,"children":1352},{"class":321,"line":1351},19,[1353,1358,1362,1367,1372,1377,1382,1387,1391,1396,1400,1405,1410],{"type":226,"tag":319,"props":1354,"children":1355},{"style":359},[1356],{"type":231,"value":1357},"azureaduser",{"type":226,"tag":319,"props":1359,"children":1360},{"style":337},[1361],{"type":231,"value":1280},{"type":226,"tag":319,"props":1363,"children":1364},{"style":326},[1365],{"type":231,"value":1366},"az",{"type":226,"tag":319,"props":1368,"children":1369},{"style":348},[1370],{"type":231,"value":1371}," ad",{"type":226,"tag":319,"props":1373,"children":1374},{"style":348},[1375],{"type":231,"value":1376}," signed-in-user",{"type":226,"tag":319,"props":1378,"children":1379},{"style":348},[1380],{"type":231,"value":1381}," show",{"type":226,"tag":319,"props":1383,"children":1384},{"style":348},[1385],{"type":231,"value":1386}," --query",{"type":226,"tag":319,"props":1388,"children":1389},{"style":337},[1390],{"type":231,"value":345},{"type":226,"tag":319,"props":1392,"children":1393},{"style":348},[1394],{"type":231,"value":1395},"objectId",{"type":226,"tag":319,"props":1397,"children":1398},{"style":337},[1399],{"type":231,"value":356},{"type":226,"tag":319,"props":1401,"children":1402},{"style":348},[1403],{"type":231,"value":1404}," -o",{"type":226,"tag":319,"props":1406,"children":1407},{"style":348},[1408],{"type":231,"value":1409}," tsv",{"type":226,"tag":319,"props":1411,"children":1412},{"style":337},[1413],{"type":231,"value":694},{"type":226,"tag":319,"props":1415,"children":1417},{"class":321,"line":1416},20,[1418],{"type":226,"tag":319,"props":1419,"children":1420},{"emptyLinePlaceholder":374},[1421],{"type":231,"value":377},{"type":226,"tag":319,"props":1423,"children":1425},{"class":321,"line":1424},21,[1426,1431,1435,1440,1445,1450],{"type":226,"tag":319,"props":1427,"children":1428},{"style":452},[1429],{"type":231,"value":1430},"echo",{"type":226,"tag":319,"props":1432,"children":1433},{"style":337},[1434],{"type":231,"value":345},{"type":226,"tag":319,"props":1436,"children":1437},{"style":348},[1438],{"type":231,"value":1439},"Creating ",{"type":226,"tag":319,"props":1441,"children":1442},{"style":359},[1443],{"type":231,"value":1444},"$resourceGroup",{"type":226,"tag":319,"props":1446,"children":1447},{"style":348},[1448],{"type":231,"value":1449},"...",{"type":226,"tag":319,"props":1451,"children":1452},{"style":337},[1453],{"type":231,"value":1116},{"type":226,"tag":319,"props":1455,"children":1457},{"class":321,"line":1456},22,[1458,1462,1467,1472,1477,1482,1487,1491,1496],{"type":226,"tag":319,"props":1459,"children":1460},{"style":326},[1461],{"type":231,"value":1366},{"type":226,"tag":319,"props":1463,"children":1464},{"style":348},[1465],{"type":231,"value":1466}," group",{"type":226,"tag":319,"props":1468,"children":1469},{"style":348},[1470],{"type":231,"value":1471}," create",{"type":226,"tag":319,"props":1473,"children":1474},{"style":348},[1475],{"type":231,"value":1476}," --name",{"type":226,"tag":319,"props":1478,"children":1479},{"style":359},[1480],{"type":231,"value":1481}," $resourceGroup ",{"type":226,"tag":319,"props":1483,"children":1484},{"style":348},[1485],{"type":231,"value":1486},"--location",{"type":226,"tag":319,"props":1488,"children":1489},{"style":337},[1490],{"type":231,"value":345},{"type":226,"tag":319,"props":1492,"children":1493},{"style":359},[1494],{"type":231,"value":1495},"$location",{"type":226,"tag":319,"props":1497,"children":1498},{"style":337},[1499],{"type":231,"value":1116},{"type":226,"tag":319,"props":1501,"children":1503},{"class":321,"line":1502},23,[1504],{"type":226,"tag":319,"props":1505,"children":1506},{"emptyLinePlaceholder":374},[1507],{"type":231,"value":377},{"type":226,"tag":319,"props":1509,"children":1511},{"class":321,"line":1510},24,[1512,1516,1520,1524,1529,1534,1538,1542],{"type":226,"tag":319,"props":1513,"children":1514},{"style":452},[1515],{"type":231,"value":1430},{"type":226,"tag":319,"props":1517,"children":1518},{"style":337},[1519],{"type":231,"value":345},{"type":226,"tag":319,"props":1521,"children":1522},{"style":348},[1523],{"type":231,"value":1439},{"type":226,"tag":319,"props":1525,"children":1526},{"style":359},[1527],{"type":231,"value":1528},"$server",{"type":226,"tag":319,"props":1530,"children":1531},{"style":348},[1532],{"type":231,"value":1533}," in ",{"type":226,"tag":319,"props":1535,"children":1536},{"style":359},[1537],{"type":231,"value":1495},{"type":226,"tag":319,"props":1539,"children":1540},{"style":348},[1541],{"type":231,"value":1449},{"type":226,"tag":319,"props":1543,"children":1544},{"style":337},[1545],{"type":231,"value":1116},{"type":226,"tag":319,"props":1547,"children":1549},{"class":321,"line":1548},25,[1550,1554,1559,1564,1568,1572,1577,1582,1586,1590,1594,1598,1602,1607,1612,1617],{"type":226,"tag":319,"props":1551,"children":1552},{"style":326},[1553],{"type":231,"value":1366},{"type":226,"tag":319,"props":1555,"children":1556},{"style":348},[1557],{"type":231,"value":1558}," sql",{"type":226,"tag":319,"props":1560,"children":1561},{"style":348},[1562],{"type":231,"value":1563}," server",{"type":226,"tag":319,"props":1565,"children":1566},{"style":348},[1567],{"type":231,"value":1471},{"type":226,"tag":319,"props":1569,"children":1570},{"style":348},[1571],{"type":231,"value":1476},{"type":226,"tag":319,"props":1573,"children":1574},{"style":359},[1575],{"type":231,"value":1576}," $server ",{"type":226,"tag":319,"props":1578,"children":1579},{"style":348},[1580],{"type":231,"value":1581},"--resource-group",{"type":226,"tag":319,"props":1583,"children":1584},{"style":359},[1585],{"type":231,"value":1481},{"type":226,"tag":319,"props":1587,"children":1588},{"style":348},[1589],{"type":231,"value":1486},{"type":226,"tag":319,"props":1591,"children":1592},{"style":337},[1593],{"type":231,"value":345},{"type":226,"tag":319,"props":1595,"children":1596},{"style":359},[1597],{"type":231,"value":1495},{"type":226,"tag":319,"props":1599,"children":1600},{"style":337},[1601],{"type":231,"value":356},{"type":226,"tag":319,"props":1603,"children":1604},{"style":348},[1605],{"type":231,"value":1606}," --admin-user",{"type":226,"tag":319,"props":1608,"children":1609},{"style":359},[1610],{"type":231,"value":1611}," $login ",{"type":226,"tag":319,"props":1613,"children":1614},{"style":348},[1615],{"type":231,"value":1616},"--admin-password",{"type":226,"tag":319,"props":1618,"children":1619},{"style":359},[1620],{"type":231,"value":1621}," $password\n",{"type":226,"tag":319,"props":1623,"children":1625},{"class":321,"line":1624},26,[1626],{"type":226,"tag":319,"props":1627,"children":1628},{"emptyLinePlaceholder":374},[1629],{"type":231,"value":377},{"type":226,"tag":319,"props":1631,"children":1633},{"class":321,"line":1632},27,[1634,1638,1642,1647],{"type":226,"tag":319,"props":1635,"children":1636},{"style":452},[1637],{"type":231,"value":1430},{"type":226,"tag":319,"props":1639,"children":1640},{"style":337},[1641],{"type":231,"value":345},{"type":226,"tag":319,"props":1643,"children":1644},{"style":348},[1645],{"type":231,"value":1646},"Configuring firewall...",{"type":226,"tag":319,"props":1648,"children":1649},{"style":337},[1650],{"type":231,"value":1116},{"type":226,"tag":319,"props":1652,"children":1654},{"class":321,"line":1653},28,[1655,1659,1663,1667,1672,1676,1681,1685,1690,1694,1699,1704,1709,1714,1719],{"type":226,"tag":319,"props":1656,"children":1657},{"style":326},[1658],{"type":231,"value":1366},{"type":226,"tag":319,"props":1660,"children":1661},{"style":348},[1662],{"type":231,"value":1558},{"type":226,"tag":319,"props":1664,"children":1665},{"style":348},[1666],{"type":231,"value":1563},{"type":226,"tag":319,"props":1668,"children":1669},{"style":348},[1670],{"type":231,"value":1671}," firewall-rule",{"type":226,"tag":319,"props":1673,"children":1674},{"style":348},[1675],{"type":231,"value":1471},{"type":226,"tag":319,"props":1677,"children":1678},{"style":348},[1679],{"type":231,"value":1680}," --resource-group",{"type":226,"tag":319,"props":1682,"children":1683},{"style":359},[1684],{"type":231,"value":1481},{"type":226,"tag":319,"props":1686,"children":1687},{"style":348},[1688],{"type":231,"value":1689},"--server",{"type":226,"tag":319,"props":1691,"children":1692},{"style":359},[1693],{"type":231,"value":1576},{"type":226,"tag":319,"props":1695,"children":1696},{"style":348},[1697],{"type":231,"value":1698},"-n",{"type":226,"tag":319,"props":1700,"children":1701},{"style":348},[1702],{"type":231,"value":1703}," AllowYourIp",{"type":226,"tag":319,"props":1705,"children":1706},{"style":348},[1707],{"type":231,"value":1708}," --start-ip-address",{"type":226,"tag":319,"props":1710,"children":1711},{"style":359},[1712],{"type":231,"value":1713}," $startIP ",{"type":226,"tag":319,"props":1715,"children":1716},{"style":348},[1717],{"type":231,"value":1718},"--end-ip-address",{"type":226,"tag":319,"props":1720,"children":1721},{"style":359},[1722],{"type":231,"value":1723}," $endIP\n",{"type":226,"tag":319,"props":1725,"children":1727},{"class":321,"line":1726},29,[1728],{"type":226,"tag":319,"props":1729,"children":1730},{"emptyLinePlaceholder":374},[1731],{"type":231,"value":377},{"type":226,"tag":319,"props":1733,"children":1735},{"class":321,"line":1734},30,[1736,1740,1744,1748,1753,1758,1762,1766],{"type":226,"tag":319,"props":1737,"children":1738},{"style":452},[1739],{"type":231,"value":1430},{"type":226,"tag":319,"props":1741,"children":1742},{"style":337},[1743],{"type":231,"value":345},{"type":226,"tag":319,"props":1745,"children":1746},{"style":348},[1747],{"type":231,"value":1439},{"type":226,"tag":319,"props":1749,"children":1750},{"style":359},[1751],{"type":231,"value":1752},"$database",{"type":226,"tag":319,"props":1754,"children":1755},{"style":348},[1756],{"type":231,"value":1757}," on ",{"type":226,"tag":319,"props":1759,"children":1760},{"style":359},[1761],{"type":231,"value":1528},{"type":226,"tag":319,"props":1763,"children":1764},{"style":348},[1765],{"type":231,"value":1449},{"type":226,"tag":319,"props":1767,"children":1768},{"style":337},[1769],{"type":231,"value":1116},{"type":226,"tag":319,"props":1771,"children":1773},{"class":321,"line":1772},31,[1774,1778,1782,1787,1791,1795,1799,1803,1807,1812,1817,1822,1827,1832,1837,1842],{"type":226,"tag":319,"props":1775,"children":1776},{"style":326},[1777],{"type":231,"value":1366},{"type":226,"tag":319,"props":1779,"children":1780},{"style":348},[1781],{"type":231,"value":1558},{"type":226,"tag":319,"props":1783,"children":1784},{"style":348},[1785],{"type":231,"value":1786}," db",{"type":226,"tag":319,"props":1788,"children":1789},{"style":348},[1790],{"type":231,"value":1471},{"type":226,"tag":319,"props":1792,"children":1793},{"style":348},[1794],{"type":231,"value":1680},{"type":226,"tag":319,"props":1796,"children":1797},{"style":359},[1798],{"type":231,"value":1481},{"type":226,"tag":319,"props":1800,"children":1801},{"style":348},[1802],{"type":231,"value":1689},{"type":226,"tag":319,"props":1804,"children":1805},{"style":359},[1806],{"type":231,"value":1576},{"type":226,"tag":319,"props":1808,"children":1809},{"style":348},[1810],{"type":231,"value":1811},"--name",{"type":226,"tag":319,"props":1813,"children":1814},{"style":359},[1815],{"type":231,"value":1816}," $database ",{"type":226,"tag":319,"props":1818,"children":1819},{"style":348},[1820],{"type":231,"value":1821},"--sample-name",{"type":226,"tag":319,"props":1823,"children":1824},{"style":348},[1825],{"type":231,"value":1826}," AdventureWorksLT",{"type":226,"tag":319,"props":1828,"children":1829},{"style":348},[1830],{"type":231,"value":1831}," --service-objective",{"type":226,"tag":319,"props":1833,"children":1834},{"style":348},[1835],{"type":231,"value":1836}," Basic",{"type":226,"tag":319,"props":1838,"children":1839},{"style":348},[1840],{"type":231,"value":1841}," --zone-redundant",{"type":226,"tag":319,"props":1843,"children":1844},{"style":337},[1845],{"type":231,"value":1846}," false\n",{"type":226,"tag":319,"props":1848,"children":1850},{"class":321,"line":1849},32,[1851],{"type":226,"tag":319,"props":1852,"children":1853},{"emptyLinePlaceholder":374},[1854],{"type":231,"value":377},{"type":226,"tag":319,"props":1856,"children":1858},{"class":321,"line":1857},33,[1859,1863,1867,1872],{"type":226,"tag":319,"props":1860,"children":1861},{"style":452},[1862],{"type":231,"value":1430},{"type":226,"tag":319,"props":1864,"children":1865},{"style":337},[1866],{"type":231,"value":345},{"type":226,"tag":319,"props":1868,"children":1869},{"style":348},[1870],{"type":231,"value":1871},"Creating AD admin in sql server...",{"type":226,"tag":319,"props":1873,"children":1874},{"style":337},[1875],{"type":231,"value":1116},{"type":226,"tag":319,"props":1877,"children":1879},{"class":321,"line":1878},34,[1880,1884,1888,1892,1897,1901,1905,1909,1914,1918,1923,1928,1933],{"type":226,"tag":319,"props":1881,"children":1882},{"style":326},[1883],{"type":231,"value":1366},{"type":226,"tag":319,"props":1885,"children":1886},{"style":348},[1887],{"type":231,"value":1558},{"type":226,"tag":319,"props":1889,"children":1890},{"style":348},[1891],{"type":231,"value":1563},{"type":226,"tag":319,"props":1893,"children":1894},{"style":348},[1895],{"type":231,"value":1896}," ad-admin",{"type":226,"tag":319,"props":1898,"children":1899},{"style":348},[1900],{"type":231,"value":1471},{"type":226,"tag":319,"props":1902,"children":1903},{"style":348},[1904],{"type":231,"value":1680},{"type":226,"tag":319,"props":1906,"children":1907},{"style":359},[1908],{"type":231,"value":1481},{"type":226,"tag":319,"props":1910,"children":1911},{"style":348},[1912],{"type":231,"value":1913},"--server-name",{"type":226,"tag":319,"props":1915,"children":1916},{"style":359},[1917],{"type":231,"value":1576},{"type":226,"tag":319,"props":1919,"children":1920},{"style":348},[1921],{"type":231,"value":1922},"--display-name",{"type":226,"tag":319,"props":1924,"children":1925},{"style":348},[1926],{"type":231,"value":1927}," ADMIN",{"type":226,"tag":319,"props":1929,"children":1930},{"style":348},[1931],{"type":231,"value":1932}," --object-id",{"type":226,"tag":319,"props":1934,"children":1935},{"style":359},[1936],{"type":231,"value":1937}," $azureaduser\n",{"type":226,"tag":319,"props":1939,"children":1941},{"class":321,"line":1940},35,[1942],{"type":226,"tag":319,"props":1943,"children":1944},{"emptyLinePlaceholder":374},[1945],{"type":231,"value":377},{"type":226,"tag":319,"props":1947,"children":1949},{"class":321,"line":1948},36,[1950,1954,1958,1963,1968,1973,1977,1982,1986,1991,1995],{"type":226,"tag":319,"props":1951,"children":1952},{"style":452},[1953],{"type":231,"value":1430},{"type":226,"tag":319,"props":1955,"children":1956},{"style":337},[1957],{"type":231,"value":345},{"type":226,"tag":319,"props":1959,"children":1960},{"style":348},[1961],{"type":231,"value":1962},"Database connection string to use: ",{"type":226,"tag":319,"props":1964,"children":1965},{"style":359},[1966],{"type":231,"value":1967},"\\\"",{"type":226,"tag":319,"props":1969,"children":1970},{"style":348},[1971],{"type":231,"value":1972},"Server=",{"type":226,"tag":319,"props":1974,"children":1975},{"style":359},[1976],{"type":231,"value":1528},{"type":226,"tag":319,"props":1978,"children":1979},{"style":348},[1980],{"type":231,"value":1981},".database.windows.net; Authentication=Active Directory Default; Database=",{"type":226,"tag":319,"props":1983,"children":1984},{"style":359},[1985],{"type":231,"value":1752},{"type":226,"tag":319,"props":1987,"children":1988},{"style":348},[1989],{"type":231,"value":1990},";",{"type":226,"tag":319,"props":1992,"children":1993},{"style":359},[1994],{"type":231,"value":1967},{"type":226,"tag":319,"props":1996,"children":1997},{"style":337},[1998],{"type":231,"value":1116},{"type":226,"tag":227,"props":2000,"children":2001},{},[2002],{"type":231,"value":2003},"This script should be self-explanatory if you have already played a little with Azure CLI. Basically, what it does is:",{"type":226,"tag":479,"props":2005,"children":2006},{},[2007,2012,2024,2029,2034],{"type":226,"tag":483,"props":2008,"children":2009},{},[2010],{"type":231,"value":2011},"create an azure SQL server",{"type":226,"tag":483,"props":2013,"children":2014},{},[2015,2017,2022],{"type":231,"value":2016},"configure the server firewall to allow you to query it from your local IP address (if you are executing the script from cloud shell, replace ",{"type":226,"tag":234,"props":2018,"children":2020},{"className":2019},[],[2021],{"type":231,"value":1275},{"type":231,"value":2023}," variable with your local machine IP)",{"type":226,"tag":483,"props":2025,"children":2026},{},[2027],{"type":231,"value":2028},"create an azure SQL database with already tables and data in it from the sample AdventureWorksLT",{"type":226,"tag":483,"props":2030,"children":2031},{},[2032],{"type":231,"value":2033},"set you logged in azure ad user as the AD administrator of the database",{"type":226,"tag":483,"props":2035,"children":2036},{},[2037],{"type":231,"value":2038},"write in the console the connection string to use in your C# code to access the database",{"type":226,"tag":227,"props":2040,"children":2041},{},[2042],{"type":231,"value":2043},"If you want to customize something do not hesitate to modify the scripts and especially variables like the resources location, the SQL server user/password, or the name of the resources. This is a bash script but if you want to execute it in PowerShell, all the Azure CLI commands should work fine, you just have to change the variables declarations as the syntax is different in PowerShell. If you don't have Azure CLI installed on your laptop you can use Azure Cloud Shell to execute this script.",{"type":226,"tag":251,"props":2045,"children":2046},{"icon":253},[2047],{"type":226,"tag":227,"props":2048,"children":2049},{},[2050,2052,2058],{"type":231,"value":2051},"If you are new to Azure CLI, you can read my article ",{"type":226,"tag":530,"props":2053,"children":2056},{"href":2054,"rel":2055},"https://www.techwatching.dev/posts/welcome-azure-cli",[534],[2057],{"type":231,"value":15},{"type":231,"value":449},{"type":226,"tag":960,"props":2060,"children":2062},{"id":2061},"querying-the-database-from-a-minima-api-in-c",[2063],{"type":231,"value":2064},"Querying the database from a minima API in C#",{"type":226,"tag":227,"props":2066,"children":2067},{},[2068,2070,2077],{"type":231,"value":2069},"Usually, I like to create a console application (with the ",{"type":226,"tag":530,"props":2071,"children":2074},{"href":2072,"rel":2073},"https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio#worker-service-template",[534],[2075],{"type":231,"value":2076},"worker service template",{"type":231,"value":2078}," for instance) for my samples, yet this time I decided to try the new minimal APIs from .NET 6 (currently in preview).",{"type":226,"tag":227,"props":2080,"children":2081},{},[2082,2084,2090],{"type":231,"value":2083},"Minimal APIs would probably deserve an entire blog post, but let's just say a minimal API in .NET 6 allow you to build a small HTTP API with less ceremony than a classic controller-based API. As all the code can be written in a ",{"type":226,"tag":234,"props":2085,"children":2087},{"className":2086},[],[2088],{"type":231,"value":2089},"Program.cs",{"type":231,"value":2091}," file, so it's very convenient when you want to quickly build a web application without too much complexity (especially if you are new to ASP.NET Core) or if you are developing a small microservice.",{"type":226,"tag":309,"props":2093,"children":2095},{"className":311,"code":2094,"language":313,"meta":207,"style":207},"using Dapper;\nusing Microsoft.Data.SqlClient;\n\nvar builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\nif (app.Environment.IsDevelopment())\n{\n    app.UseDeveloperExceptionPage();\n}\n\napp.MapGet(\"/\", async () =>\n{\n    using var connection = new SqlConnection(\"Server=server-testingmsi28497.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi28497;\");\n    var products = await connection.QueryAsync\u003CProduct>(\"SELECT TOP 10 ProductID, Name from [SalesLT].[Product]\");\n    return products;\n});\n\napp.Run();\n\npublic record Product(int ProductID, string Name);\n",[2096],{"type":226,"tag":234,"props":2097,"children":2098},{"__ignoreMap":207},[2099,2116,2149,2156,2199,2232,2239,2279,2286,2307,2314,2321,2375,2382,2431,2497,2513,2521,2528,2548,2555],{"type":226,"tag":319,"props":2100,"children":2101},{"class":321,"line":322},[2102,2107,2112],{"type":226,"tag":319,"props":2103,"children":2105},{"style":2104},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[2106],{"type":231,"value":387},{"type":226,"tag":319,"props":2108,"children":2109},{"style":359},[2110],{"type":231,"value":2111}," Dapper",{"type":226,"tag":319,"props":2113,"children":2114},{"style":337},[2115],{"type":231,"value":367},{"type":226,"tag":319,"props":2117,"children":2118},{"class":321,"line":370},[2119,2123,2128,2132,2137,2141,2145],{"type":226,"tag":319,"props":2120,"children":2121},{"style":2104},[2122],{"type":231,"value":387},{"type":226,"tag":319,"props":2124,"children":2125},{"style":359},[2126],{"type":231,"value":2127}," Microsoft",{"type":226,"tag":319,"props":2129,"children":2130},{"style":337},[2131],{"type":231,"value":449},{"type":226,"tag":319,"props":2133,"children":2134},{"style":359},[2135],{"type":231,"value":2136},"Data",{"type":226,"tag":319,"props":2138,"children":2139},{"style":337},[2140],{"type":231,"value":449},{"type":226,"tag":319,"props":2142,"children":2143},{"style":359},[2144],{"type":231,"value":843},{"type":226,"tag":319,"props":2146,"children":2147},{"style":337},[2148],{"type":231,"value":367},{"type":226,"tag":319,"props":2150,"children":2151},{"class":321,"line":380},[2152],{"type":226,"tag":319,"props":2153,"children":2154},{"emptyLinePlaceholder":374},[2155],{"type":231,"value":377},{"type":226,"tag":319,"props":2157,"children":2158},{"class":321,"line":433},[2159,2163,2168,2172,2177,2181,2186,2190,2195],{"type":226,"tag":319,"props":2160,"children":2161},{"style":326},[2162],{"type":231,"value":329},{"type":226,"tag":319,"props":2164,"children":2165},{"style":326},[2166],{"type":231,"value":2167}," builder",{"type":226,"tag":319,"props":2169,"children":2170},{"style":337},[2171],{"type":231,"value":340},{"type":226,"tag":319,"props":2173,"children":2174},{"style":359},[2175],{"type":231,"value":2176}," WebApplication",{"type":226,"tag":319,"props":2178,"children":2179},{"style":337},[2180],{"type":231,"value":449},{"type":226,"tag":319,"props":2182,"children":2183},{"style":452},[2184],{"type":231,"value":2185},"CreateBuilder",{"type":226,"tag":319,"props":2187,"children":2188},{"style":337},[2189],{"type":231,"value":420},{"type":226,"tag":319,"props":2191,"children":2192},{"style":359},[2193],{"type":231,"value":2194},"args",{"type":226,"tag":319,"props":2196,"children":2197},{"style":337},[2198],{"type":231,"value":908},{"type":226,"tag":319,"props":2200,"children":2201},{"class":321,"line":731},[2202,2206,2211,2215,2219,2223,2228],{"type":226,"tag":319,"props":2203,"children":2204},{"style":326},[2205],{"type":231,"value":329},{"type":226,"tag":319,"props":2207,"children":2208},{"style":326},[2209],{"type":231,"value":2210}," app",{"type":226,"tag":319,"props":2212,"children":2213},{"style":337},[2214],{"type":231,"value":340},{"type":226,"tag":319,"props":2216,"children":2217},{"style":359},[2218],{"type":231,"value":2167},{"type":226,"tag":319,"props":2220,"children":2221},{"style":337},[2222],{"type":231,"value":449},{"type":226,"tag":319,"props":2224,"children":2225},{"style":452},[2226],{"type":231,"value":2227},"Build",{"type":226,"tag":319,"props":2229,"children":2230},{"style":337},[2231],{"type":231,"value":460},{"type":226,"tag":319,"props":2233,"children":2234},{"class":321,"line":740},[2235],{"type":226,"tag":319,"props":2236,"children":2237},{"emptyLinePlaceholder":374},[2238],{"type":231,"value":377},{"type":226,"tag":319,"props":2240,"children":2241},{"class":321,"line":1148},[2242,2247,2251,2256,2260,2265,2269,2274],{"type":226,"tag":319,"props":2243,"children":2244},{"style":384},[2245],{"type":231,"value":2246},"if",{"type":226,"tag":319,"props":2248,"children":2249},{"style":337},[2250],{"type":231,"value":392},{"type":226,"tag":319,"props":2252,"children":2253},{"style":359},[2254],{"type":231,"value":2255},"app",{"type":226,"tag":319,"props":2257,"children":2258},{"style":337},[2259],{"type":231,"value":449},{"type":226,"tag":319,"props":2261,"children":2262},{"style":359},[2263],{"type":231,"value":2264},"Environment",{"type":226,"tag":319,"props":2266,"children":2267},{"style":337},[2268],{"type":231,"value":449},{"type":226,"tag":319,"props":2270,"children":2271},{"style":452},[2272],{"type":231,"value":2273},"IsDevelopment",{"type":226,"tag":319,"props":2275,"children":2276},{"style":337},[2277],{"type":231,"value":2278},"())\n",{"type":226,"tag":319,"props":2280,"children":2281},{"class":321,"line":1178},[2282],{"type":226,"tag":319,"props":2283,"children":2284},{"style":337},[2285],{"type":231,"value":702},{"type":226,"tag":319,"props":2287,"children":2288},{"class":321,"line":1186},[2289,2294,2298,2303],{"type":226,"tag":319,"props":2290,"children":2291},{"style":359},[2292],{"type":231,"value":2293},"    app",{"type":226,"tag":319,"props":2295,"children":2296},{"style":337},[2297],{"type":231,"value":449},{"type":226,"tag":319,"props":2299,"children":2300},{"style":452},[2301],{"type":231,"value":2302},"UseDeveloperExceptionPage",{"type":226,"tag":319,"props":2304,"children":2305},{"style":337},[2306],{"type":231,"value":460},{"type":226,"tag":319,"props":2308,"children":2309},{"class":321,"line":1212},[2310],{"type":226,"tag":319,"props":2311,"children":2312},{"style":337},[2313],{"type":231,"value":1078},{"type":226,"tag":319,"props":2315,"children":2316},{"class":321,"line":1243},[2317],{"type":226,"tag":319,"props":2318,"children":2319},{"emptyLinePlaceholder":374},[2320],{"type":231,"value":377},{"type":226,"tag":319,"props":2322,"children":2323},{"class":321,"line":1251},[2324,2328,2332,2337,2341,2345,2350,2354,2359,2365,2370],{"type":226,"tag":319,"props":2325,"children":2326},{"style":359},[2327],{"type":231,"value":2255},{"type":226,"tag":319,"props":2329,"children":2330},{"style":337},[2331],{"type":231,"value":449},{"type":226,"tag":319,"props":2333,"children":2334},{"style":452},[2335],{"type":231,"value":2336},"MapGet",{"type":226,"tag":319,"props":2338,"children":2339},{"style":337},[2340],{"type":231,"value":420},{"type":226,"tag":319,"props":2342,"children":2343},{"style":337},[2344],{"type":231,"value":356},{"type":226,"tag":319,"props":2346,"children":2347},{"style":348},[2348],{"type":231,"value":2349},"/",{"type":226,"tag":319,"props":2351,"children":2352},{"style":337},[2353],{"type":231,"value":356},{"type":226,"tag":319,"props":2355,"children":2356},{"style":337},[2357],{"type":231,"value":2358},",",{"type":226,"tag":319,"props":2360,"children":2362},{"style":2361},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[2363],{"type":231,"value":2364}," async",{"type":226,"tag":319,"props":2366,"children":2367},{"style":337},[2368],{"type":231,"value":2369}," ()",{"type":226,"tag":319,"props":2371,"children":2372},{"style":337},[2373],{"type":231,"value":2374}," =>\n",{"type":226,"tag":319,"props":2376,"children":2377},{"class":321,"line":1260},[2378],{"type":226,"tag":319,"props":2379,"children":2380},{"style":337},[2381],{"type":231,"value":702},{"type":226,"tag":319,"props":2383,"children":2384},{"class":321,"line":1269},[2385,2390,2394,2398,2402,2406,2410,2414,2418,2423,2427],{"type":226,"tag":319,"props":2386,"children":2387},{"style":384},[2388],{"type":231,"value":2389},"    using",{"type":226,"tag":319,"props":2391,"children":2392},{"style":326},[2393],{"type":231,"value":656},{"type":226,"tag":319,"props":2395,"children":2396},{"style":326},[2397],{"type":231,"value":444},{"type":226,"tag":319,"props":2399,"children":2400},{"style":337},[2401],{"type":231,"value":340},{"type":226,"tag":319,"props":2403,"children":2404},{"style":337},[2405],{"type":231,"value":410},{"type":226,"tag":319,"props":2407,"children":2408},{"style":326},[2409],{"type":231,"value":415},{"type":226,"tag":319,"props":2411,"children":2412},{"style":337},[2413],{"type":231,"value":420},{"type":226,"tag":319,"props":2415,"children":2416},{"style":337},[2417],{"type":231,"value":356},{"type":226,"tag":319,"props":2419,"children":2420},{"style":348},[2421],{"type":231,"value":2422},"Server=server-testingmsi28497.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi28497;",{"type":226,"tag":319,"props":2424,"children":2425},{"style":337},[2426],{"type":231,"value":356},{"type":226,"tag":319,"props":2428,"children":2429},{"style":337},[2430],{"type":231,"value":908},{"type":226,"tag":319,"props":2432,"children":2433},{"class":321,"line":1307},[2434,2439,2444,2448,2452,2456,2460,2465,2470,2475,2480,2484,2489,2493],{"type":226,"tag":319,"props":2435,"children":2436},{"style":326},[2437],{"type":231,"value":2438},"    var",{"type":226,"tag":319,"props":2440,"children":2441},{"style":326},[2442],{"type":231,"value":2443}," products",{"type":226,"tag":319,"props":2445,"children":2446},{"style":337},[2447],{"type":231,"value":340},{"type":226,"tag":319,"props":2449,"children":2450},{"style":337},[2451],{"type":231,"value":578},{"type":226,"tag":319,"props":2453,"children":2454},{"style":359},[2455],{"type":231,"value":444},{"type":226,"tag":319,"props":2457,"children":2458},{"style":337},[2459],{"type":231,"value":449},{"type":226,"tag":319,"props":2461,"children":2462},{"style":452},[2463],{"type":231,"value":2464},"QueryAsync",{"type":226,"tag":319,"props":2466,"children":2467},{"style":337},[2468],{"type":231,"value":2469},"\u003C",{"type":226,"tag":319,"props":2471,"children":2472},{"style":326},[2473],{"type":231,"value":2474},"Product",{"type":226,"tag":319,"props":2476,"children":2477},{"style":337},[2478],{"type":231,"value":2479},">(",{"type":226,"tag":319,"props":2481,"children":2482},{"style":337},[2483],{"type":231,"value":356},{"type":226,"tag":319,"props":2485,"children":2486},{"style":348},[2487],{"type":231,"value":2488},"SELECT TOP 10 ProductID, Name from [SalesLT].[Product]",{"type":226,"tag":319,"props":2490,"children":2491},{"style":337},[2492],{"type":231,"value":356},{"type":226,"tag":319,"props":2494,"children":2495},{"style":337},[2496],{"type":231,"value":908},{"type":226,"tag":319,"props":2498,"children":2499},{"class":321,"line":1325},[2500,2505,2509],{"type":226,"tag":319,"props":2501,"children":2502},{"style":384},[2503],{"type":231,"value":2504},"    return",{"type":226,"tag":319,"props":2506,"children":2507},{"style":359},[2508],{"type":231,"value":2443},{"type":226,"tag":319,"props":2510,"children":2511},{"style":337},[2512],{"type":231,"value":367},{"type":226,"tag":319,"props":2514,"children":2515},{"class":321,"line":1333},[2516],{"type":226,"tag":319,"props":2517,"children":2518},{"style":337},[2519],{"type":231,"value":2520},"});\n",{"type":226,"tag":319,"props":2522,"children":2523},{"class":321,"line":1342},[2524],{"type":226,"tag":319,"props":2525,"children":2526},{"emptyLinePlaceholder":374},[2527],{"type":231,"value":377},{"type":226,"tag":319,"props":2529,"children":2530},{"class":321,"line":1351},[2531,2535,2539,2544],{"type":226,"tag":319,"props":2532,"children":2533},{"style":359},[2534],{"type":231,"value":2255},{"type":226,"tag":319,"props":2536,"children":2537},{"style":337},[2538],{"type":231,"value":449},{"type":226,"tag":319,"props":2540,"children":2541},{"style":452},[2542],{"type":231,"value":2543},"Run",{"type":226,"tag":319,"props":2545,"children":2546},{"style":337},[2547],{"type":231,"value":460},{"type":226,"tag":319,"props":2549,"children":2550},{"class":321,"line":1416},[2551],{"type":226,"tag":319,"props":2552,"children":2553},{"emptyLinePlaceholder":374},[2554],{"type":231,"value":377},{"type":226,"tag":319,"props":2556,"children":2557},{"class":321,"line":1424},[2558,2563,2568,2573,2578,2583,2587,2591,2596],{"type":226,"tag":319,"props":2559,"children":2560},{"style":2361},[2561],{"type":231,"value":2562},"public",{"type":226,"tag":319,"props":2564,"children":2565},{"style":326},[2566],{"type":231,"value":2567}," record",{"type":226,"tag":319,"props":2569,"children":2570},{"style":326},[2571],{"type":231,"value":2572}," Product",{"type":226,"tag":319,"props":2574,"children":2575},{"style":337},[2576],{"type":231,"value":2577},"(int",{"type":226,"tag":319,"props":2579,"children":2580},{"style":326},[2581],{"type":231,"value":2582}," ProductID",{"type":226,"tag":319,"props":2584,"children":2585},{"style":337},[2586],{"type":231,"value":2358},{"type":226,"tag":319,"props":2588,"children":2589},{"style":337},[2590],{"type":231,"value":616},{"type":226,"tag":319,"props":2592,"children":2593},{"style":326},[2594],{"type":231,"value":2595}," Name",{"type":226,"tag":319,"props":2597,"children":2598},{"style":337},[2599],{"type":231,"value":908},{"type":226,"tag":227,"props":2601,"children":2602},{},[2603],{"type":231,"value":2604},"As you can see this code is only 26 lines long:",{"type":226,"tag":479,"props":2606,"children":2607},{},[2608,2621,2635,2647],{"type":226,"tag":483,"props":2609,"children":2610},{},[2611,2613,2619],{"type":231,"value":2612},"there is only one route, that returns the Product identifiers and names from the table ",{"type":226,"tag":234,"props":2614,"children":2616},{"className":2615},[],[2617],{"type":231,"value":2618},"[SalesLT].[Product]",{"type":231,"value":2620}," of the database created with the previous Azure CLI script",{"type":226,"tag":483,"props":2622,"children":2623},{},[2624,2626,2633],{"type":231,"value":2625},"the SQL query is done by using the micro ORM ",{"type":226,"tag":530,"props":2627,"children":2630},{"href":2628,"rel":2629},"https://github.com/DapperLib/Dapper",[534],[2631],{"type":231,"value":2632},"Dapper",{"type":231,"value":2634}," which simplifies the boilerplate code to query an SQL database while keeping performance",{"type":226,"tag":483,"props":2636,"children":2637},{},[2638,2640,2645],{"type":231,"value":2639},"the result of the SQL query is mapped to a record class ",{"type":226,"tag":234,"props":2641,"children":2643},{"className":2642},[],[2644],{"type":231,"value":2474},{"type":231,"value":2646}," which is declared in one line",{"type":226,"tag":483,"props":2648,"children":2649},{},[2650,2652,2657,2659,2664],{"type":231,"value":2651},"the code uses ",{"type":226,"tag":234,"props":2653,"children":2655},{"className":2654},[],[2656],{"type":231,"value":239},{"type":231,"value":2658}," v3.0.0 with the ",{"type":226,"tag":234,"props":2660,"children":2662},{"className":2661},[],[2663],{"type":231,"value":247},{"type":231,"value":818},{"type":226,"tag":227,"props":2666,"children":2667},{},[2668],{"type":226,"tag":2669,"props":2670,"children":2676},"img",{"alt":2671,"className":2672,"src":2675},"C# code querying an SQL Database using Active Directory Default authentication mode.",[2673,2674],"rounded-lg","mx-auto","/posts/images/sqlclient_minapi_1.png",[],{"type":226,"tag":251,"props":2678,"children":2679},{"icon":253},[2680],{"type":226,"tag":227,"props":2681,"children":2682},{},[2683,2685,2691],{"type":231,"value":2684},"To keep things simple, I am connecting to the database with the Azure AD account which is an admin of the SQL server. But I could also have assigned a role with lower permissions to my account, see ",{"type":226,"tag":530,"props":2686,"children":2689},{"href":2687,"rel":2688},"https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi#grant-permissions-to-managed-identity",[534],[2690],{"type":231,"value":946},{"type":231,"value":2692}," for more information on how to do that.",{"type":226,"tag":281,"props":2694,"children":2696},{"id":2695},"to-conclude",[2697],{"type":231,"value":2698},"To conclude",{"type":226,"tag":227,"props":2700,"children":2701},{},[2702,2704,2710],{"type":231,"value":2703},"While building an application interacting with Azure we often neglect to use mechanisms like Azure AD authentication that remove the need for secrets. But as we have seen in this article some libraries like ",{"type":226,"tag":234,"props":2705,"children":2707},{"className":2706},[],[2708],{"type":231,"value":2709},"Microsoft.Data.Sql.Client",{"type":231,"value":2711}," or the Azure SDKs allow us to do that quite easily. I love how connecting to an Azure SQL Database in C# is becoming more simple and more secure at the same time.",{"type":226,"tag":2713,"props":2714,"children":2715},"style",{},[2716],{"type":231,"value":2717},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":207,"searchDepth":370,"depth":370,"links":2719},[2720,2721,2722,2724,2728],{"id":283,"depth":370,"text":286},{"id":510,"depth":370,"text":513},{"id":808,"depth":370,"text":2723},"Here comes Active Directory Default authentication mode",{"id":950,"depth":370,"text":953,"children":2725},[2726,2727],{"id":962,"depth":380,"text":965},{"id":2061,"depth":380,"text":2064},{"id":2695,"depth":370,"text":2698},"markdown","content:1.posts:20.sqlclient-active-directory-authent.md","content","1.posts/20.sqlclient-active-directory-authent.md","md",[2735,2751],{"_path":70,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":69,"description":2736,"lead":2737,"date":2738,"image":2739,"badge":2741,"tags":2742,"_type":2729,"_id":2749,"_source":2731,"_file":2750,"_extension":2733},"In my previous articles about winget I talked about installing packages but I did not talk about producing packages for Windows Package Manager. So let's set things right.","Automate the upgrade of a winget package with GitHub Actions and Winget Create.","2021-08-25T00:00:00.000Z",{"src":2740},"/images/surface_2.jpg",{"label":214},[2743,2744,2745,2746,2747,2748],"winget","wingetcreate","package manager","tooling","nushell","GitHub Actions","content:1.posts:21.wingetcreate.md","1.posts/21.wingetcreate.md",{"_path":64,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":63,"description":2752,"lead":2753,"date":2754,"image":2755,"badge":2757,"tags":2759,"_type":2729,"_id":2762,"_source":2731,"_file":2763,"_extension":2733},"This week I learned some Azure CLI commands, how to have JSON IntelliSense in vscode and that Azure Storage Explorer was usable again.","IntelliSense in vscode, Azure CLI command to get assigned roles, and Azure Storage Explorer new version.","2021-06-07T00:00:00.000Z",{"src":2756},"/images/surface_1.jpg",{"label":2758},"Tips",[2760,2761,220,219],"tips learned this week","vscode","content:1.posts:19.w22-2021-tips-learned-this-week.md","1.posts/19.w22-2021-tips-learned-this-week.md",1716749601639]