<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://shazwazza.com/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Shazwazza</title>
    <link>https://shazwazza.com/</link>
    <description>My blog which is pretty much just all about coding</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <image>
      <url>/media/0libq25y/frog.png?rmode=max&amp;v=1da0e911f4e6890</url>
      <title>Shazwazza</title>
      <link>https://shazwazza.com/</link>
    </image>
    <item>
      <guid isPermaLink="false">1239</guid>
      <link>https://shazwazza.com/post/examine-and-azure-blob-storage/</link>
      <category>Umbraco</category>
      <category>Examine</category>
      <title>Examine and Azure Blob Storage</title>
      <description>&lt;p&gt;Quite some time ago - probably close to 2 years - I created an alpha version of an extension library to Examine to allow storing Lucene indexes in Blob Storage called &lt;em&gt;Examine.AzureDirectory&lt;/em&gt;. This idea isn’t new at all and in fact there’s been a library to do this for many years called &lt;a rel="noopener" href="https://github.com/azure-contrib/AzureDirectory" target="_blank"&gt;AzureDirectory&lt;/a&gt; but it previously had issues and it wasn’t clear on exactly what it’s limitations are. The &lt;a rel="noopener" href="https://github.com/Shazwazza/Examine/tree/master/src/Examine.AzureDirectory" target="_blank"&gt;Examine.AzureDirectory&lt;/a&gt; implementation was built using a lot of the original code of AzureDirectory but has a bunch of fixes (which I contributed back to the project) and different ways of working with the data. Also since Examine 0.1.90 still worked with lucene 2.x, this also made this compatible with the older Lucene version.&lt;/p&gt;
&lt;p&gt;… And 2 years later, I’ve actually released a real version &lt;/p&gt;
&lt;h2&gt;Why is this needed?&lt;/h2&gt;
&lt;p&gt;There’s a couple reasons – firstly Azure web apps storage run on a network share and Lucene absolutely does not like it’s files hosted on a network share, this will bring all sorts of strange performance issues among other things. The way AzureDirectory works is to store the ‘master’ index in Blob Storage and then sync the required Lucene files to the local ‘fast drive’. In Azure web apps there’s 2x drives: ‘slow drive’ (the network share) and the ‘fast drive’ which is the local server’s temp files on local storage with limited space. By syncing the Lucene files to the local fast drive it means that Lucene is no longer operating over a network share. When writes occur, it writes back to the local fast drive and then pushes those changes back to the master index in Blob Storage. This isn’t the only way to overcome this limitation of Lucene, in fact Examine has shipped a work around for many years which uses something called SyncDirectory which does more or less the same thing but instead of storing the master index in Blob Storage, the master index is just stored on the ‘slow drive’.  Someone has actually taken this code and &lt;a rel="noopener" href="https://github.com/yohsii/SyncDirectory" target="_blank"&gt;made a separate standalone project&lt;/a&gt; with this logic called SyncDirectory which is pretty cool!&lt;/p&gt;
&lt;h2&gt;Load balancing/Scaling&lt;/h2&gt;
&lt;p&gt;There’s a couple of ways to work around the network share storage in Azure web apps (as above), but in my opinion the main reason why this is important is for load balancing and being able to scale out. Since Lucene doesn’t work well over a network share, it means that Lucene files must exist local to the process it’s running in. That means that when you are load balancing or scaling out, each server that is handling requests will have it’s own local Lucene index. So what happens when you scale out further and another new worker goes online? This really depending on the hosting application… for example in Umbraco, this would mean that the new worker will create it’s own local indexes by rebuilding the indexes from the source data (i.e. database). This isn’t an ideal scenario especially in Umbraco v7 where requests won’t be served until the index is built and ready. A better scenario is that the new worker comes online and then syncs an existing index from master storage that is shared between all workers …. yes! like Blob Storage.&lt;/p&gt;
&lt;h3&gt;Read/Write vs Read only&lt;/h3&gt;
&lt;p&gt;Lucene can’t be written to concurrently by multiple processes. There are some workarounds here a there to try to achieve this by synchronizing processes with named mutex/semaphore locks and even AzureSearch tries to handle some of this by utilizing Blob Storage leases but it’s not a seamless experience. This is one of the reasons why Umbraco requires a ‘master’ web app for writing and a separate web app for scaling which guarantees that only one process writes to the indexes. This is the setup that &lt;em&gt;Examine.AzureDirectory&lt;/em&gt; supports too and on the front-end/replica/slave web app that scales you will configure the provider to be readonly which guarantees it will never try to write back to the (probably locked) Blob Storage.&lt;/p&gt;
&lt;p&gt;With this in place, when a new front-end worker goes online it doesn’t need to rebuild it’s own local indexes, it will just check if indexes exist and to do that will make sure the master index is there and then continue booting. At this stage there’s actually almost no performance overhead. Nothing actually happens with the local indexes until the index is referenced by this worker and when that happens Examine will lazily just sync the Lucene files that it needs locally.&lt;/p&gt;
&lt;h2&gt;How do I get it?&lt;/h2&gt;
&lt;p&gt;First thing to point out is that this first release is only for Examine 0.1.90 which is for Umbraco v7. Support for Examine 1.x and Umbraco 8.x will come out very soon with some slightly different install instructions.&lt;/p&gt;
&lt;p&gt;The &lt;a rel="noopener" href="https://github.com/Shazwazza/Examine/releases/tag/v0.1.90-azure-directory" target="_blank"&gt;release notes of this are here&lt;/a&gt;, the &lt;a rel="noopener" href="https://github.com/Shazwazza/Examine/wiki/Examine-with-Azure-Directory-(Blob-Storage)" target="_blank"&gt;install docs are here&lt;/a&gt;, and the Nuget package for this can be found &lt;a rel="noopener" href="https://www.nuget.org/packages/Examine.AzureDirectory" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PM&amp;gt; Install-Package Examine.AzureDirectory -Version 0.1.90&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To activate it, you need to add these settings to your web.config&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-xml"&gt;&amp;lt;add key="examine:AzureStorageConnString" value="YOUR-STORAGE-CONNECTION-STRING" /&amp;gt;
&amp;lt;add key="examine:AzureStorageContainer" value="YOUR-CONTAINER-NAME" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then for your master server/web app you’ll want to add a &lt;em&gt;directoryFactory&lt;/em&gt; attribute to each of your indexers in &lt;em&gt;ExamineSettings.config&lt;/em&gt;, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-xml"&gt;&amp;lt;add name="InternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"
      supportUnpublished="true"
      supportProtected="true"
      directoryFactory="Examine.AzureDirectory.AzureDirectoryFactory, Examine.AzureDirectory"
      analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For your front-end/replicate/slave server you’ll want a different readonly value for the &lt;em&gt;directoryFactory&lt;/em&gt; like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-xml"&gt;&amp;lt;add name="InternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"
      supportUnpublished="true"
      supportProtected="true"
      directoryFactory="Examine.AzureDirectory.ReadOnlyAzureDirectoryFactory, Examine.AzureDirectory"
      analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net"/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Does it work?&lt;/h2&gt;
&lt;p&gt;Great question :) With the testing that I’ve done it works and I’ve had this running on this site for all of last year without issue but I haven’t rigorously tested this at scale with high traffic sites, etc… I’ve decided to release a real version of this because having this as an alpha/proof of concept means that nobody will test or use it. So now hopefully a few of you will give this a whirl and let everyone know how it goes. Any bugs can be submitted to the &lt;a rel="noopener" href="https://github.com/Shazwazza/Examine" target="_blank"&gt;Examine repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:09:45 Z</pubDate>
      <a10:updated>2023-03-23T15:09:45Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1213</guid>
      <link>https://shazwazza.com/post/configuring-azure-active-directory-login-with-umbraco-members/</link>
      <category>ASP.Net</category>
      <category>Web Development</category>
      <category>Umbraco</category>
      <title>Configuring Azure Active Directory login with Umbraco Members</title>
      <description>&lt;p&gt;This post is about configuring Azure Active Directory with Umbraco &lt;u&gt;Members&lt;/u&gt; (not &lt;em&gt;Users&lt;/em&gt;), meaning this is for your front-end website, not the Umbraco back office. I did write up a post about Azure AD with back office users though, so if that is what you are looking for then &lt;a href="https://shazwazza.com/post/configuring-azure-active-directory-login-with-umbraco/" target="_blank"&gt;this is the link&lt;/a&gt;. &lt;/p&gt;&lt;h2&gt;Install the Nuget packages&lt;/h2&gt;&lt;p&gt;First thing to do is get the &lt;a href="https://www.nuget.org/packages/UmbracoIdentity" target="_blank"&gt;UmbracoIdentity&lt;/a&gt; package installed. &lt;/p&gt;

&lt;div style="width: 100%;"&gt;
&lt;div style="padding: 10px; color: rgb(255, 255, 255); line-height: 1.5; font-family: consolas, menlo, monaco,&amp;quot;Courier New&amp;quot;, monospace; background-color: rgb(0, 36, 64);"&gt;PM &amp;gt; Install-Package UmbracoIdentity&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(This will also install the UmbracoIdentity.Core base package)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This package installs some code snippets and updates your web.config to enable ASP.Net Identity for Umbraco members. Umbraco ships with the old and deprecated ASP.Net Membership Providers for members and not ASP.Net Identity so this package extends the Umbraco CMS and the Umbraco members implementation to use ASP.Net Identity APIs to interact with the built in members data store. Installing this package will remove the (deprecated) FormsAuthentication module from your web.config and it will no longer be used to authenticate members, so the typical members snippets built into Umbraco macros will not work. Instead use the supplied snippets shipped with this package.&lt;/p&gt;&lt;p&gt;To read more about this package see the &lt;a href="https://github.com/Shazwazza/UmbracoIdentity" target="_blank"&gt;GitHub repo here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, the OpenIdConnect package needs to be installed&lt;/p&gt;

&lt;div style="width: 100%;"&gt;
&lt;div style="padding: 10px; color: rgb(255, 255, 255); line-height: 1.5; font-family: consolas, menlo, monaco,&amp;quot;Courier New&amp;quot;, monospace; background-color: rgb(0, 36, 64);"&gt;PM &amp;gt; Install-Package Microsoft.Owin.Security.OpenIdConnect&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Configure Azure Active Directory&lt;/h2&gt;&lt;p&gt;Head over to the &lt;em&gt;Azure Active Directory &lt;/em&gt;section on the Azure portal, choose &lt;em&gt;App Registrations &lt;/em&gt;(I’m using the Preview functionality for this) and create a &lt;em&gt;New registration&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_4.png"&gt;&lt;img width="802" height="362" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_1.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Next fill out the app details&lt;/h3&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_22.png"&gt;&lt;img width="802" height="805" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_10.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You may also need to enter other redirect URLs depending on how many different environments you have. All of these URLs can be added in the Authentication section of your app in the Azure portal.&lt;/p&gt;&lt;p&gt;For AAD configuration for front-end members, the redirect Urls are just your website’s root URL and it is advised to keep the trailing slash. &lt;/p&gt;&lt;h3&gt;Next you will need to enable Id Tokens&lt;/h3&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_12.png"&gt;&lt;img width="802" height="559" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_5.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Configure OpenIdConnect&lt;/h2&gt;&lt;p&gt;The UmbracoIdentity package will have installed an OWIN startup class in &lt;em&gt;~/App_Start/UmbracoIdentityStartup.cs &lt;/em&gt;(or it could be in App_Code if you are using a website project)&lt;em&gt;. &lt;/em&gt;This is how ASP.Net Identity is configured for front-end members and where you can specify the configuration for different OAuth providers. There’s a few things you’ll need to do:&lt;/p&gt;&lt;h3&gt;Allow external sign in cookies&lt;/h3&gt;&lt;p&gt;If you scroll down to the &lt;em&gt;ConfigureMiddleware &lt;/em&gt;method, there will be a link of code to uncomment: &lt;em&gt;app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); &lt;/em&gt;this is required for any OAuth providers to work.&lt;/p&gt;&lt;h3&gt;Enable OpenIdConnect OAuth for AAD&lt;/h3&gt;&lt;p&gt;You’ll need to add this extension method class to your code which is some boiler plate code to configure OpenIdConnect with AAD:&lt;/p&gt;

&lt;pre class="lang-csharp"&gt;&lt;code&gt;public static class UmbracoADAuthExtensions
{
    public static void ConfigureAzureActiveDirectoryAuth(this IAppBuilder app,
        string tenant, string clientId, string postLoginRedirectUri, Guid issuerId,
        string caption = "Active Directory")
    {
        var authority = string.Format(
            System.Globalization.CultureInfo.InvariantCulture,
            "https://login.windows.net/{0}",
            tenant);

        var adOptions = new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = authority,
            RedirectUri = postLoginRedirectUri
        };

        adOptions.Caption = caption;
        //Need to set the auth type as the issuer path
        adOptions.AuthenticationType = string.Format(
            System.Globalization.CultureInfo.InvariantCulture,
            "https://sts.windows.net/{0}/",
            issuerId);
        app.UseOpenIdConnectAuthentication(adOptions);
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next you’ll need to call this code, add the following line underneath the &lt;em&gt;app.UseExternalSignInCookie&lt;/em&gt; method call: &lt;/p&gt;

&lt;pre class="lang-csharp"&gt;&lt;code&gt;app.ConfigureAzureActiveDirectoryAuth(
    ConfigurationManager.AppSettings["azureAd:tenantId"],
    ConfigurationManager.AppSettings["azureAd:clientId"],
    //The value of this will need to change depending on your current environment
    postLoginRedirectUri: ConfigurationManager.AppSettings["azureAd:redirectUrl"],
    //This is the same as the TenantId
    issuerId: new Guid(ConfigurationManager.AppSettings["azureAd:tenantId"]));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you’ll need to add a few appSettings to your web.config (based on your AAD info):&lt;/p&gt;

&lt;pre class="lang-csharp"&gt;&lt;code&gt;&amp;lt;add key="azureAd:tenantId" value="YOUR-TENANT-ID-GUID" /&amp;gt;
&amp;lt;add key="azureAd:clientId" value="YOUR-CLIENT-ID-GUID" /&amp;gt;
&amp;lt;add key="azureAd:redirectUrl" value="http://my-test-website/" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Configure your Umbraco data&lt;/h2&gt;&lt;p&gt;The UmbracoIdentity repository has the &lt;a href="https://github.com/Shazwazza/UmbracoIdentity#installation" target="_blank"&gt;installation documentation&lt;/a&gt; and you must follow these 2 instructions, and they are very simple:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="https://github.com/Shazwazza/UmbracoIdentity/wiki#2-member-type-updates" target="_blank"&gt;You need to update your member type with the securityStamp property&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/Shazwazza/UmbracoIdentity/wiki#3-creating-the-account-page" target="_blank"&gt;Create the Account document type&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Once that is done you will have an Member account management page which is based off of the installed views and snippets of the UmbracoIdentity package. This account page will look like this:&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_8.png"&gt;&lt;img width="802" height="305" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_3.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As you can see the button text under the “Use another service to log in” is the login provider name which is a bit ugly. The good news is that this is easy to change since this is just a partial view that was installed with the UmbracoIdentity package. You can edit the file: &lt;em&gt;~/Views/UmbracoIdentityAccount/ExternalLoginsList.cshtml&lt;/em&gt;, the code to render that button text is using &lt;em&gt;@p.Authentication&lt;/em&gt; provider but we can easily change this to &lt;em&gt;@p.Caption&lt;/em&gt; which is actually the same caption text used in the extension method we created. So the whole button code can look like this instead:&lt;/p&gt;
&lt;pre class="lang-html"&gt;&lt;code&gt;
&amp;lt;button type="submit" class="btn btn-default"
        id="@p.AuthenticationType"
        name="provider"
        value="@p.AuthenticationType"
        title="Log in using your @p.Caption account"&amp;gt;
    @p.Caption
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a bit nicer, now the button looks like:&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_10.png"&gt;&lt;img width="802" height="192" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_4.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The purpose of all of these snippets and views installed with UmbracoIdentity is for you to customize how the whole flow looks and works so you’ll most likely end up customizing a number of views found in this folder to suit your needs.&lt;/p&gt;&lt;h2&gt;That’s it!&lt;/h2&gt;&lt;p&gt;Once that’s all configured, if you click on the Active Directory button to log in as a member, you’ll be brought to the standard AAD permission screen:&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_18.png"&gt;&lt;img width="402" height="434" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_8.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Once you accept you’ll be redirect back to your Account page:&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_20.png"&gt;&lt;img width="802" height="930" title="image" style="display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-active-directory-login_c313-image_thumb_9.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Any customizations is then up to you. You can modify how the flow works, whether or not you accepting auto-linking accounts (like in the above example), or if you require a member to exist locally before being able to link an OAuth account, etc… All of the views and controller code in UmbracoIdentity is there for you to manipulate. The main files are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;~/Views/Account.cshtml&lt;/li&gt;&lt;li&gt;~/Views/UmbracoIdentityAccount/*&lt;/li&gt;&lt;li&gt;~/Controllers/UmbracoIdentityAccountController.cs&lt;/li&gt;&lt;li&gt;~/App_Start/UmbracoIdentityStartup.cs&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Happy coding!&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:09:08 Z</pubDate>
      <a10:updated>2023-03-23T15:09:08Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1302</guid>
      <link>https://shazwazza.com/post/configuring-azure-active-directory-login-with-umbraco/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>Configuring Azure Active Directory login with Umbraco</title>
      <description>&lt;p&gt;It’s been a while since I first set this up and back then not all of these settings were in the new Azure portal, but now that they are getting this all configured is quite easy so here’s the basic steps!&lt;/p&gt;
&lt;h2&gt;Install the Nuget package&lt;/h2&gt;
&lt;p&gt;First thing to do is get the &lt;a rel="noopener" href="https://www.nuget.org/packages/UmbracoCms.IdentityExtensions.AzureActiveDirectory" target="_blank"&gt;UmbracoCms.IdentityExtensions.AzureActiveDirectory&lt;/a&gt; package installed&lt;/p&gt;
&lt;div style="width: 100%;"&gt;
&lt;div style="padding: 10px; color: #ffffff; line-height: 1.5; font-family: consolas, menlo, monaco,'Courier New', monospace; background-color: #002440;"&gt;PM &amp;gt; Install-Package UmbracoCms.IdentityExtensions.AzureActiveDirectory&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(This will also install the UmbracoCms.IdentityExtensions base package)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Configure Azure Active Directory&lt;/h2&gt;
&lt;p&gt;Head over to the &lt;em&gt;Azure Active Directory &lt;/em&gt;section on the Azure portal, choose &lt;em&gt;App Registrations &lt;/em&gt;(I’m using the Preview functionality for this) and create a &lt;em&gt;New registration&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_4.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_1.png" border="0" alt="image" title="image" width="802" height="362" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Next fill out the app details&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_6.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_2.png" border="0" alt="image" title="image" width="802" height="805" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Add your redirect URLs for any additional environments&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_10.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_4.png" border="0" alt="image" title="image" width="802" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;If you have local, dev, staging, live, etc… sites, you’ll need to configure those URLs here, always make sure it’s the Umbraco path with a trailing slash.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Make note of some settings&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_8.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_3.png" border="0" alt="image" title="image" width="802" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The settings you’ll need to copy are the Application/Client ID and the Tenant ID along with the redirect URLs.&lt;/p&gt;
&lt;h2&gt;Configure you application&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Add the Client Id, Tenant Id and redirect URL to AppSettings. I’ve used the keys: azureAd:tenantId, azureAd:clientId, azureAd:redirectUrl but you can choose whatever you like.&lt;/li&gt;
&lt;li&gt;Open the &lt;em&gt;App_Start/UmbracoStandardOwinStartup.cs&lt;/em&gt; file that was installed with the IdentityExtensions pakage&lt;/li&gt;
&lt;li&gt;Underneath the call to &lt;em&gt;base.Configuration(app); &lt;/em&gt;add the block of code that was shown in the readme shown after you installed the Nuget package which looks like this:
&lt;pre&gt;&lt;code class="lang-csharp"&gt;app.ConfigureBackOfficeAzureActiveDirectoryAuth(
    //The Tenant can also be "YOURDIRECTORYNAME.onmicrosoft.com"
    tenant: ConfigurationManager.AppSettings["azureAd:tenantId"],
    clientId: ConfigurationManager.AppSettings["azureAd:clientId"],
    //The value of this will need to change depending on your current environment
    postLoginRedirectUri: ConfigurationManager.AppSettings["azureAd:redirectUrl"],
    //This is the same as the TenantId
    issuerId: new Guid(ConfigurationManager.AppSettings["azureAd:tenantId"]));
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Ensure that this OWIN startup class is defined in your web.config: &lt;em&gt;&amp;lt;add key="owin:appStartup" value="UmbracoStandardOwinStartup" /&amp;gt;  &lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;That's it!&lt;/h2&gt;
&lt;p&gt;Once you’ve got this configured, and you login to the back office normally you can then link your AD account:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_12.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_5.png" border="0" alt="image" title="image" width="802" height="409" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once linked, you can login with this provider:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_14.png"&gt;&lt;img style="border: 0px currentcolor; display: inline; background-image: none;" src="https://shazwazza.com/media/articulate/open-live-writer-configuring-azure-ad-oauth-login-with-um_bc18-image_thumb_6.png" border="0" alt="image" title="image" width="802" height="495" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Auto linking?&lt;/h2&gt;
&lt;p&gt;If you configured your AD App to only authenticate “only accounts in this organization”, you might want to auto-link Umbraco back office accounts. Auto-linking will automatically ensure that a local Umbraco user account exists for any user that logs in via the AD provider. This is handy if you want to do all of your user administration via Azure AD. Auto-linking can be configured as part of your OWIN startup class.&lt;/p&gt;
&lt;p&gt;I won’t cover auto-linking in this post but there are some &lt;a rel="noopener" href="https://our.umbraco.com/documentation/Reference/Security/#auto-linking-accounts-for-custom-oauth-providers" target="_blank"&gt;docs&lt;/a&gt; available for that.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:09:04 Z</pubDate>
      <a10:updated>2023-03-23T15:09:04Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1281</guid>
      <link>https://shazwazza.com/post/getting-umbraco-to-work-with-azure-easy-auth/</link>
      <category>ASP.Net</category>
      <category>Umbraco</category>
      <title>Getting Umbraco to work with Azure Easy Auth</title>
      <description>&lt;p&gt;There’s a nifty feature in your Azure App Service that allows you to very quickly add authentication and authorization to your Azure website. You’ll see most folks calling this “Easy Auth” and there’s quite a few articles on the subject such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/tech-feed/azure-active-directorys-hidden-feature-easy-auth-315e34d92249" title="https://medium.com/tech-feed/azure-active-directorys-hidden-feature-easy-auth-315e34d92249"&gt;https://medium.com/tech-feed/azure-active-directorys-hidden-feature-easy-auth-315e34d92249&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-us/resources/videos/azure-websites-easy-authentication-and-authorization-with-chris-gillum/" title="https://azure.microsoft.com/en-us/resources/videos/azure-websites-easy-authentication-and-authorization-with-chris-gillum/"&gt;https://azure.microsoft.com/en-us/resources/videos/azure-websites-easy-authentication-and-authorization-with-chris-gillum/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-overview" title="https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-overview"&gt;https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The good news is this all works the way you’d expect with an Umbraco website for front-end requests but unfortunately this doesn’t play nicely with the Umbraco back office … but it’s easy to configure Umbraco to work!&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;The problem is that if you turn on Easy Auth and try to log in to your Umbraco back office, the login will succeed but you’ll get 401 responses for other back office requests and essentially you’ll see a blank screen. The reason this happens is due to the way that Easy Auth works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It activates an HttpModule in your site called &lt;strong&gt;EasyAuthAspNetThreadPrincipalModule&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;During the &lt;em&gt;HttpModule.AuthenticateRequest&lt;/em&gt; stage it replaces the &lt;em&gt;Thread.CurrentPrincipal&lt;/em&gt; with it’s own &lt;em&gt;ClaimsPrincipal&lt;/em&gt;/&lt;em&gt;ClaimsIdentity&lt;/em&gt; instance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Umbraco also sets the &lt;em&gt;Thread.CurrentPrincipal.Identity &lt;/em&gt;during this phase but at the OWIN level which executes before the &lt;em&gt;EasyAuthAspNetThreadPrincipalModule. &lt;/em&gt;Because the Easy Auth module replaces the principal/identity, it wipes out the one created by Umbraco. What it should do instead is check if the current principal is a &lt;em&gt;ClaimsPrincipal &lt;/em&gt;and then add it’s identity to the identity collection instead of wiping out anything that is already there. If that were the case, everything would ‘just work’ but since it is not we have to work around this issue.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;UPDATE!&lt;/strong&gt; &lt;em&gt;(19/04/18) - &lt;a rel="noopener" href="https://twitter.com/cgillum" target="_blank" title="Chris Gillum"&gt;Chris Gillum&lt;/a&gt; who created Easy Auth got in touch with me on Twitter to share some &lt;a href="https://github.com/cgillum/easyauth/wiki"&gt;handy (and fairly hidden) documentation&lt;/a&gt; for Easy Auth. Looks like another work around is to use the &lt;a href="https://github.com/cgillum/easyauth/wiki/Advanced-Application-Settings"&gt;WEBSITE_AUTH_DISABLE_IDENTITY_FLOW&lt;/a&gt; appSetting which will prevent Easy Auth from setting the thread identity at all.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To work around this problem we need to tell Umbraco to perform it’s authentication procedure &lt;strong&gt;after&lt;/strong&gt; the Easy Auth module runs which is actually pretty easy to do.&lt;/p&gt;
&lt;p&gt;Create a new OWIN startup class:&lt;/p&gt;
&lt;pre class="lang-csharp"&gt;&lt;code&gt;
[assembly: OwinStartup("MyOwinStartup", typeof(MyOwinStartup))]
namespace MyProject
{
    public class MyOwinStartup : Umbraco.Web.UmbracoDefaultOwinStartup
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Update an appSetting in your web.config to tell OWIN to use your class:&lt;/p&gt;
&lt;pre class="lang-xml"&gt;&lt;code&gt;
&amp;lt;add key="owin:appStartup" value="MyOwinStartup" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Override the method that configures Umbraco's authentication procedure and tell it to execute after the default Authentication stage, notice this code block is using PipelineStage.PostAuthenticate:&lt;/p&gt;
&lt;pre class="lang-csharp"&gt;&lt;code&gt;
public class MyOwinStartup : Umbraco.Web.UmbracoDefaultOwinStartup
{
    protected override void ConfigureUmbracoAuthentication(IAppBuilder app)
    {
        app
            .UseUmbracoBackOfficeCookieAuthentication(ApplicationContext, PipelineStage.PostAuthenticate)
            .UseUmbracoBackOfficeExternalCookieAuthentication(ApplicationContext, PipelineStage.PostAuthenticate)
            .UseUmbracoPreviewAuthentication(ApplicationContext, PipelineStage.Authorize);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it! Now the Umbraco back office will authenticate correctly with Azure Easy Auth turned on.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:56 Z</pubDate>
      <a10:updated>2023-03-23T15:08:56Z</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1264</guid>
      <link>https://shazwazza.com/post/deploying-to-azure-from-vsts-using-publish-profiles-and-msdeploy/</link>
      <category>Web Development</category>
      <category>etc...</category>
      <category>Hosting</category>
      <category>Servers</category>
      <title>Deploying to Azure from VSTS using publish profiles and msdeploy</title>
      <description>&lt;p&gt;In almost all of the examples online about how to deploy various services to Azure, they always list the super easy way to do it and that is to authenticate your current account to your Azure subscription which then grants your VSTS build to do all sorts of things… The problem is that not everyone has the security clearance to use the super easy tools in VSTS.&lt;/p&gt;&lt;p&gt;When you attempt to use these nice tools in VSTS you might get an error like this: &lt;font color="#f79646"&gt;“Failed to set Azure permission ‘RoleAssignmentId: some-guid-goes-here’ for the service principal … does not have authorizationto perform action ‘Microsoft.Authorization/roleAssignments/write’ over scope”&lt;/font&gt; This is because these nice VSTS tools actually creates a custom user behind the scenes in your azure subscription to use but your account doesn’t have access to authorize that.&lt;/p&gt;&lt;p&gt;Luckily there’s a work around&lt;/p&gt;&lt;h2&gt;MS Deploy … sigh&lt;/h2&gt;&lt;p&gt;Maybe there are other work arounds but this works, however it’s not the most elegant. I thought I’d post my findings here because it was a bit of a pain in the ass to get this all correct.&lt;/p&gt;&lt;p&gt;So here’s the steps:&lt;/p&gt;&lt;h3&gt;1. Download the publish profile&lt;/h3&gt;&lt;p&gt;You need to get the publish profile from your app service that you want to deploy to. This can be a website, a staging slot, an Azure function, (probably a bunch of others)&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_2.png"&gt;&lt;img width="600" height="185" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_thumb.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The file downloaded is an XML file containing a bunch of info you’ll need&lt;/p&gt;&lt;h3&gt;2. Create a release definition and environment for your deployment&lt;/h3&gt;&lt;p&gt;&lt;em&gt;This assumes that you are pretty familiar with VSTS&lt;/em&gt;&lt;/p&gt;&lt;p&gt;You’ll want to create an empty environment in your release definition. Normally this is where you could choose the built in fancy VSTS deployment templates like “Azure App Service Deployment” … but as above, this doesn’t work if you don’t have security clearance. Instead, choose ‘Empty’&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_4.png"&gt;&lt;img width="600" height="330" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_thumb_1.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then in your environment tasks, add Batch Script&lt;/p&gt;&lt;p&gt;&lt;a href="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_6.png"&gt;&lt;img width="600" height="312" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-image_thumb_2.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;3. Setup your batch script&lt;/h3&gt;&lt;p&gt;There’s 2 ways to go about this and both depend on a msdeploy build output. This build output is generated by your build in VSTS if you are using a standard VSTS Visual Studio solution build. This will create msdeploy packages for you and will have put them in your artifacts folder. Along with msdeploy packages this will also generate a cmd batch file that executes msdeploy and a readme file to tell you how to execute it which contains some important info that you should read.&lt;/p&gt;&lt;p&gt;So here’s 2 options: Execute the cmd file, or execute msdeploy.exe directly&lt;/p&gt;&lt;h2&gt;Execute the cmd file&lt;/h2&gt;&lt;p&gt;There’s a bit of documentation about this online but most of it is based on using the SetParameters.xml file to adjust settings… but i just don’t want to use that. &lt;/p&gt;&lt;p&gt;Here’s the Path and Arguments that you need to run:&lt;/p&gt;


&lt;pre class="language-batch"&gt;&lt;code&gt;$(System.DefaultWorkingDirectory)/YOUR_BUILD_NAME/drop/YOUR_MSBUILD_PACKAGE.deploy.cmd&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=" language-batch"&gt;&lt;code&gt;/y "/m:https://${publishUrl}/MSDeploy.axd?site=${msdeploySite}" /u:$(userName) /p:$(userPWD) /a:Basic -enableRule:DoNotDeleteRule "-setParam:name='IIS Web Application Name',value='${msdeploySite}'"

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The parameters should be added to your VSTS Variables: ${msdeploySite}, $(userName), $(userPWD) and these variables correspond exactly to what is in your publish profile XML file that you downloaded. These parameters need to be pretty much exact, any misplaced quote or if you don’t include https, etc… will cause this to fail.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: the use of &lt;strong&gt;-enableRule:DoNotDeleteRule&lt;/strong&gt; is totally optional, if you want to reset your site to exactly what is in the msdeploy package you do not want this. If however, you have user generated images, content or custom config files that exist on your site and you don’t want them deleted when you deploy, then you need to set this.&lt;/p&gt;&lt;p&gt;I’m unsure if this will work for Azure Functions deployment (it might!) … but I used the next option to do that:&lt;/p&gt;&lt;h2&gt;Execute msdeploy.exe directly&lt;/h2&gt;&lt;p&gt;If you execute the CMD file, you’ll see in the VSTS logs the exact msdeploy signature used which is:&lt;/p&gt;
&lt;pre class="language-batch"&gt;&lt;code&gt;"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='d:\a\r1\a\YOUR_PROJECT_NAME\drop\YOUR_MSDEPLOY_PACKAGE_FILE.zip' -dest:auto,computerName="https://YOUR_PUBLISH_URL/MSDeploy.axd?site=YOUR_PROFILE_NAME",userName=********,password=********,authtype="Basic",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"d:\a\r1\a\YOUR_PROJECT_NAME\drop\YOUR_MSDEPLOY_PACKAGE_FILE.SetParameters.xml" -enableRule:DoNotDeleteRule -setParam:name='IIS Web Application Name',value='YOUR_PROFILE_NAME'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So if you wanted, you could take this and execute that directly instead of the CMD file. I use this method to deploy Azure Functions but the script is a little simpler since that deployment doesn’t require all of these parameters. For that I use this for the Path and Arguments:&lt;/p&gt;
&lt;pre class="language-batch"&gt;&lt;code&gt;C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe&lt;/code&gt;&lt;/pre&gt;


&lt;pre class="language-batch"&gt;&lt;code&gt;-verb:sync -source:package='$(System.DefaultWorkingDirectory)/YOUR_BUILD_NAME/drop/YOUR_MSDEPLOY_PACKAGE.zip' -dest:auto,computerName="https://$(publishUrl)/msdeploy.axd?site=$(msdeploySite)",UserName='$(userName)',Password='$(userPWD)',AuthType='Basic' -setParam:name='IIS Web Application Name',value='$(msdeploySite)'&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Hopefully this comes in handy for someone &lt;img class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="https://shazwazza.com/media/articulate/open-live-writer-deploying-to-azure_ead7-wlemoticon-winkingsmile_2.png"&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 23 Mar 2023 15:08:44 Z</pubDate>
      <a10:updated>2023-03-23T15:08:44Z</a10:updated>
    </item>
  </channel>
</rss>