<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Matt&#039;s work blog</title>
	<atom:link href="https://mattfrear.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://mattfrear.com</link>
	<description>.NET development from Tauranga</description>
	<lastBuildDate>Thu, 21 Aug 2025 03:54:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<site xmlns="com-wordpress:feed-additions:1">12300335</site><cloud domain='mattfrear.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://secure.gravatar.com/blavatar/c46345fb58461a9cdde554603c9ac4dc2c86e20dc65329400adcf0b695598bef?s=96&#038;d=https%3A%2F%2Fs0.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Matt&#039;s work blog</title>
		<link>https://mattfrear.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://mattfrear.com/osd.xml" title="Matt&#039;s work blog" />
	<atom:link rel='hub' href='https://mattfrear.com/?pushpress=hub'/>
	<item>
		<title>Remove false-positive health check Failures in Azure API Management</title>
		<link>https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/</link>
					<comments>https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Mon, 04 Aug 2025 22:13:20 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[azure-api-management]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1709</guid>

					<description><![CDATA[A client of mine has the following configuration for many of their apps Azure API Management (Consumption plan) in front of an Azure Service Bus Topic and An Azure Function to process messages from the topic, with Azure Application Insights for monitoring everything and A static metric alert rule against the Application Insights instance, for &#8230; <a href="https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/" class="more-link">Continue reading <span class="screen-reader-text">Remove false-positive health check Failures in Azure API&#160;Management</span></a>]]></description>
										<content:encoded><![CDATA[<p>A client of mine has the following configuration for many of their apps</p>
<ul>
<li>Azure API Management (Consumption plan) in front of an</li>
<li>Azure Service Bus Topic and</li>
<li>An Azure Function to process messages from the topic, with</li>
<li>Azure Application Insights for monitoring everything and</li>
<li>A static metric alert rule against the Application Insights instance, for Exceptions &gt; 0 which</li>
<li>Sends an email to an MS Teams email address which</li>
<li>Posts an alert to MS Teams, whenever any exception occurs</li>
</ul>
<p>Every day at around the same time, something mysterious (which doesn&#8217;t belong to us) pings all of their Azure API Management instances at site root, i.e. GET /. We don&#8217;t know what it is, but I guess it&#8217;s something to do with Azure Monitoring or infrastructure, or a keep alive or something. Our APIM doesn&#8217;t have anything at site root /, so it returns a 404. This 404 is counted as an Exception which is logged as a regular Failure in Application Insights:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg"><img data-attachment-id="1715" data-permalink="https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/app-insights/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg" data-orig-size="2499,1108" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="app-insights" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=700" class="alignnone size-large wp-image-1715" src="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=700" alt="Application insights showing a failure at 9:20am every day for the last 7 days" width="700" height="310" srcset="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>Which means every day at the same time we get false positive alerts (activated + deactivated) in our Teams channel:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg"><img data-attachment-id="1717" data-permalink="https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/teams/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg" data-orig-size="1701,1171" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="teams" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=700" class="alignnone size-large wp-image-1717" src="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=700" alt="MS teams alerts" width="700" height="482" srcset="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>The workaround is quite simple &#8211; add a &#8220;health check&#8221; endpoint at APIM&#8217;s site root to return a 200 instead of a 404. We can use APIM&#8217;s mock-response for this:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg"><img data-attachment-id="1719" data-permalink="https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/apim/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg" data-orig-size="2290,1269" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="apim" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=700" class="alignnone size-large wp-image-1719" src="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=700" alt="Azure API Management API showing an endpoint" width="700" height="388" srcset="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>N.B. make sure the API&#8217;s URL scheme is both <strong>HTTP</strong> and <strong>HTTPS</strong>.</p>
<p>The inbound policy looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;policies&gt;
  &lt;inbound&gt;
    &lt;base /&gt;
    &lt;rate-limit calls=&quot;1000&quot; renewal-period=&quot;60&quot; /&gt;
    &lt;mock-response status-code=&quot;200&quot; content-type=&quot;application/json&quot; /&gt;
  &lt;/inbound&gt;
  &lt;backend&gt;
    &lt;base /&gt;
  &lt;/backend&gt;
  &lt;outbound&gt;
    &lt;base /&gt;
  &lt;/outbound&gt;
  &lt;on-error&gt;
    &lt;base /&gt;
  &lt;/on-error&gt;
&lt;/policies&gt;
</pre>
<p>And here&#8217;s a Bicep snippet to deploy it. Pro-tip: you can use &#8221;&#8217; to embed the XML:</p>
<pre class="brush: plain; title: ; notranslate">
resource healthPolicy &#039;Microsoft.ApiManagement/service/apis/operations/policies@2023-05-01-preview&#039; = {
  parent: healthOperation
  name: &#039;policy&#039;
  properties: {
    format: &#039;xml&#039;
    value: &#039;&#039;&#039;
&lt;policies&gt;
  &lt;inbound&gt;
    &lt;base /&gt;
    &lt;rate-limit calls=&quot;1000&quot; renewal-period=&quot;60&quot; /&gt;
    &lt;mock-response status-code=&quot;200&quot; content-type=&quot;application/json&quot; /&gt;
  &lt;/inbound&gt;
  &lt;backend&gt;
    &lt;base /&gt;
  &lt;/backend&gt;
  &lt;outbound&gt;
    &lt;base /&gt;
  &lt;/outbound&gt;
  &lt;on-error&gt;
    &lt;base /&gt;
  &lt;/on-error&gt;
&lt;/policies&gt;
&#039;&#039;&#039;
  }
}
</pre>
<p>Hopefully that helps someone.</p>
<p>Edit, a few days later:</p>
<p>Once we implemented the mock-response, that didn&#8217;t fix the problem of the alerts being fired. Whatever is calling us has a very short timeout, so our 404s became replaced with ClientConnectionFailure exceptions.</p>
<p>The workaround I settled on is to change our static metric alert on &#8220;Exceptions &gt; 0&#8221; to a Custom Log search, and I explicitly exclude errors when calling the site root URL, with a custom query</p>
<p>exceptions<br />
| where operation_Name != &#8220;GET /&#8221;<br />
| project TimeGenerated = timestamp, problemId</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg"><img loading="lazy" data-attachment-id="1735" data-permalink="https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/alert/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg" data-orig-size="795,756" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="alert" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=700" class="alignnone size-large wp-image-1735" src="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=700" alt="azure portal alert rule" width="700" height="666" srcset="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg 795w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2025/08/05/remove-false-positive-health-check-failures-in-azure-apim/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1709</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/08/app-insights.jpg?w=700" medium="image">
			<media:title type="html">Application insights showing a failure at 9:20am every day for the last 7 days</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/08/teams.jpg?w=700" medium="image">
			<media:title type="html">MS teams alerts</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/08/apim.jpg?w=700" medium="image">
			<media:title type="html">Azure API Management API showing an endpoint</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/08/alert.jpg?w=700" medium="image">
			<media:title type="html">azure portal alert rule</media:title>
		</media:content>
	</item>
		<item>
		<title>Customize Blazor WASM sidebar per environment</title>
		<link>https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/</link>
					<comments>https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Wed, 21 May 2025 01:48:55 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Blazor]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1696</guid>

					<description><![CDATA[Our client wanted to have a slightly different color scheme for our internal application for each environment, i.e. dev, test and production. I implemented this by injecting an IConfiguration which I wrote about in 2024. The component we need to change is in MainLayout.razor, the div with class=&#8221;sidebar&#8221;. I&#8217;m not sure how to change the &#8230; <a href="https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/" class="more-link">Continue reading <span class="screen-reader-text">Customize Blazor WASM sidebar per&#160;environment</span></a>]]></description>
										<content:encoded><![CDATA[<p>Our client wanted to have a slightly different color scheme for our internal application for each environment, i.e. dev, test and production.</p>
<p>I implemented this by injecting an IConfiguration which <a href="https://mattfrear.com/2024/03/15/blazor-wasm-configuration/">I wrote about in 2024</a>.</p>
<p>The component we need to change is in MainLayout.razor, the div with class=&#8221;sidebar&#8221;.<br />
I&#8217;m not sure how to change the css via code, or if it&#8217;s possible, so I used an inline style to the div.</p>
<p>MainLayout.razor:</p>
<pre class="brush: xml; title: ; notranslate">
@inherits LayoutComponentBase
@inject IConfiguration Configuration
&lt;div class=&quot;page&quot;&gt;
    &lt;div class=&quot;sidebar&quot; style=&quot;background-image: linear-gradient(180deg, @SidebarTopColor 0%, @SidebarBottomColor 70%);&quot;&gt;
        &lt;NavMenu /&gt;
    &lt;/div&gt;
&lt;FluentDialogProvider /&gt;
&lt;FluentTooltipProvider /&gt;
&lt;FluentMessageBarProvider /&gt;

@code {
    private string SidebarTopColor = &quot;#052767&quot;; // dark sapphire blue - these are the Blazor default colors
    private string SidebarBottomColor = &quot;#3a0647&quot;; // dark purple
    protected override void OnInitialized()
    {
        var environment = Configuration[&quot;Environment&quot;]?.ToLowerInvariant() ?? &quot;local&quot;;
        switch (environment)
        {
            case &quot;dev&quot;:
                SidebarTopColor = &quot;#b4b369&quot;; // yellowy greeny
                SidebarBottomColor = &quot;#545432&quot;; // dark olive green
                break;
            case &quot;test&quot;:
                SidebarTopColor = &quot;#40651b&quot;; // greenish
                SidebarBottomColor = &quot;#294211&quot;; // dark green
                break;
            case &quot;prod&quot;:
                SidebarTopColor = &quot;#0854A0&quot;; // victoria blue
                SidebarBottomColor = &quot;#354a5f&quot;; // dark blue grey
                break;
        }
    }
}
</pre>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg"><img loading="lazy" data-attachment-id="1701" data-permalink="https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/dev/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg" data-orig-size="1279,600" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="dev" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=700" src="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=700" alt="" width="700" height="328" class="alignnone size-large wp-image-1701" srcset="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=1024 1024w, https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg 1279w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg"><img loading="lazy" data-attachment-id="1702" data-permalink="https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/test/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg" data-orig-size="1334,607" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="test" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=700" src="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=700" alt="" width="700" height="319" class="alignnone size-large wp-image-1702" srcset="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=1024 1024w, https://mattfrear.com/wp-content/uploads/2025/05/test.jpg 1334w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg"><img loading="lazy" data-attachment-id="1703" data-permalink="https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/prod/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg" data-orig-size="1290,613" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="prod" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=700" src="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=700" alt="" width="700" height="333" class="alignnone size-large wp-image-1703" srcset="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=1024 1024w, https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg 1290w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2025/05/21/customize-blazor-wasm-sidebar-per-environment/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1696</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/05/dev.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/05/test.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/05/prod.jpg?w=700" medium="image" />
	</item>
		<item>
		<title>PSA: Bicep templates run in parallel</title>
		<link>https://mattfrear.com/2025/02/14/1674/</link>
					<comments>https://mattfrear.com/2025/02/14/1674/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Fri, 14 Feb 2025 04:41:03 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[bicep]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1674</guid>

					<description><![CDATA[I had a problem recently where my Bicep templates were failing with an obscure error message: The incoming request is not recognized as a namespace policy put request. The Bicep in question was attempting to assign an Azure Service Bus topic subscription&#8217;s forwardTo to another queue. I had ordered everything in the Bicep file correctly, &#8230; <a href="https://mattfrear.com/2025/02/14/1674/" class="more-link">Continue reading <span class="screen-reader-text">PSA: Bicep templates run in&#160;parallel</span></a>]]></description>
										<content:encoded><![CDATA[<p>I had a problem recently where my Bicep templates were failing with an obscure error message:</p>
<blockquote><p>The incoming request is not recognized as a namespace policy put request.</p></blockquote>
<p>The Bicep in question was attempting to assign an Azure Service Bus topic subscription&#8217;s forwardTo to another queue.</p>
<p>I had ordered everything in the Bicep file correctly, i.e.</p>
<ol>
<li>Create the topic</li>
<li>Create its subscriptions</li>
<li>Create the queues</li>
<li>Tell the topic subscription to forward messages to the queue</li>
</ol>
<p>However, when I looked at the Deployments in the Azure Resource Group, it appeared that they weren&#8217;t running in the order I had specified:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg"><img loading="lazy" data-attachment-id="1677" data-permalink="https://mattfrear.com/2025/02/14/1674/deployments/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg" data-orig-size="2457,1074" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="deployments" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=700" class="alignnone size-large wp-image-1677" src="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=700" alt="" width="700" height="306" srcset="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>This is because by default <a href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/resource-dependencies">Bicep templates will run in parallel</a>, unless it detects dependencies. And because my templates were a bit too clever with variables and modules, Bicep was unable to detect my implicit dependencies.</p>
<p>The fix then was to be explicit with my dependencies, using the dependsOn keyword:</p>
<pre class="brush: plain; highlight: [28,59]; title: ; notranslate">
// create service bus topics And subscriptions
param topicsAndSubscriptions array = [
  {
	topicName: &#039;property~changed~v1&#039;  // ~ is what Azure uses for a forward slash, so this topic is actually property/changed/v1
	sanitizedName: &#039;property-changed&#039; // Azure doesn&#039;t like ~ or / in deployment names.
	subscriptions: [
	  &#039;ozone&#039;
	  &#039;valor&#039;
	]
  }
]

module serviceBusTopicsModule &#039;./serviceBusTopic.bicep&#039; = [for item in topicsAndSubscriptions : {
  name: &#039;serviceBusTopic-${item.sanitizedName}-${deploymentNameSuffix}&#039;
	params: {
	serviceBusName: serviceBusModule.outputs.serviceBusOutput.name
	topicName: item.topicName 
  }
}]

module topicsSubscriptionModule &#039;serviceBusTopicSubscription.bicep&#039; = [ for item in topicsAndSubscriptions: {
  name: &#039;topicSubscription-${item.sanitizedName}-${deploymentNameSuffix}&#039;
  params: {
	serviceBusName: serviceBusModule.outputs.serviceBusOutput.name
	topicName: item.topicName
	subscriptions: item.subscriptions
  }
  dependsOn: serviceBusTopicsModule
}]

// Create service bus queues
param queueSettings array = [
	{	
		name: &#039;ozone-property-changed-sbq&#039;
		requiresDuplicateDetection: true
	}
	{
		name: &#039;valor-property-changed-sbq&#039;
		requiresDuplicateDetection: false
	}
]

module serviceBusQueueModule &#039;./serviceBusQueue.bicep&#039; = {
  name: &#039;serviceBusQueue-${deploymentNameSuffix}&#039;
  params: {
	serviceBusName: serviceBusModule.outputs.serviceBusOutput.name
	queueSettings: queueSettings
  }
}

module serviceBusTopicSubsciptionForwardModule &#039;./serviceBusTopicSubscriptionForward.bicep&#039; = {
  name: &#039;serviceBusTopicSubsciptionForward-${deploymentNameSuffix}&#039;
  params: {
	serviceBusName: serviceBusModule.outputs.serviceBusOutput.name
	topicName: &#039;property~changed~v1&#039;
	subscriptionName: &#039;valor&#039;
	queueName: &#039;valor-property-changed-sbq&#039;
  }
  dependsOn: [serviceBusQueueModule, topicsSubscriptionModule]
}
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2025/02/14/1674/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1674</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2025/02/deployments.jpg?w=700" medium="image" />
	</item>
		<item>
		<title>Azure DevOps Advanced Security not detecting vulnerabilities &#8211; 0 components found</title>
		<link>https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/</link>
					<comments>https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Thu, 21 Nov 2024 04:17:16 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1656</guid>

					<description><![CDATA[Today at a client I noticed that when I built a solution in Visual Studio, I would get Warnings about security vulnerabilities in third party NuGet packages: We had previously setup Azure DevOp&#8217;s &#8220;Advanced Security&#8221; in our Build pipelines a while ago, so we should have already been alerted to this vulnerability, by the AdvancedSecurity-Dependency-Scanning@1 &#8230; <a href="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/" class="more-link">Continue reading <span class="screen-reader-text">Azure DevOps Advanced Security not detecting vulnerabilities &#8211; 0 components&#160;found</span></a>]]></description>
										<content:encoded><![CDATA[<p>Today at a client I noticed that when I built a solution in Visual Studio, I would get Warnings about security vulnerabilities in third party NuGet packages:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg"><img loading="lazy" data-attachment-id="1658" data-permalink="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/vs-vulnerabilities/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg" data-orig-size="2506,486" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="vs-vulnerabilities" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=700" class="alignnone size-large wp-image-1658" src="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=700" alt="A screenshot from Visual Studio showing NuGet vulnerabilites as Warnings in the Error List." width="700" height="136" srcset="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>We had previously setup Azure DevOp&#8217;s &#8220;Advanced Security&#8221; in our Build pipelines a while ago, so we should have already been alerted to this vulnerability, by the AdvancedSecurity-Dependency-Scanning@1 task. When I looked at the task&#8217;s output, it was rather empty:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg"><img loading="lazy" data-attachment-id="1660" data-permalink="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/2-scanning-fail/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg" data-orig-size="1836,1414" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2-scanning-fail" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=700" class="alignnone size-large wp-image-1660" src="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=700" alt="0 components found" width="700" height="539" srcset="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>This is because the AdvancedSecurity-Dependency-Scanning@1 task needs to have the packages already downloaded &#8211; by either doing a dotnet restore first, or a dotnet build.</p>
<p>The code scanning pipeline looked like this:</p>
<pre class="brush: yaml; title: ; notranslate">
steps:
- task: NuGetAuthenticate@1 # needed to authenticate for our private NuGet feed
- task: AdvancedSecurity-Codeql-Init@1
  inputs:
    languages: &quot;csharp&quot;
- task: AdvancedSecurity-Dependency-Scanning@1
- task: AdvancedSecurity-Codeql-Autobuild@1
- task: AdvancedSecurity-Codeql-Analyze@1
- task: AdvancedSecurity-Publish@1

</pre>
<p>&nbsp;</p>
<p>You&#8217;ll notice that I already have an &#8220;Autobuild&#8221; task there. The fix then was to move the AdvancedSecurity-Dependency-Scanning@1 to after the AdvancedSecurity-Codeql-Autobuild@1 task:</p>
<pre class="brush: yaml; title: ; notranslate">
steps:
- task: NuGetAuthenticate@1 # needed to authenticate for Tcc.Common@Local NuGet feed
- task: AdvancedSecurity-Codeql-Init@1 # Initializes the CodeQL database in preparation for building.
  inputs:
    languages: &quot;csharp&quot;
- task: AdvancedSecurity-Codeql-Autobuild@1 # Build project for CodeQL analysis 
- task: AdvancedSecurity-Codeql-Analyze@1 # Analyzes the code to find security vulnerabilities and coding errors.
- task: AdvancedSecurity-Dependency-Scanning@1 # scans NuGets for vulnerabilities - this needs to be after the autobuild task.
- task: AdvancedSecurity-Publish@1 # Publishes the results of the analysis to the Azure DevOps pipeline.
</pre>
<p>&nbsp;</p>
<p>Once that was done the task detected 237 NuGet components:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg"><img loading="lazy" data-attachment-id="1665" data-permalink="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/3-task-results/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg" data-orig-size="1065,970" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3-task-results" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=700" class="alignnone size-large wp-image-1665" src="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=700" alt="237 components found on NuGet" width="700" height="638" srcset="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=1024 1024w, https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg 1065w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>I could now see a vulnerability reported as a Build warning:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg"><img loading="lazy" data-attachment-id="1664" data-permalink="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/3-build-results/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg" data-orig-size="2082,1096" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3-build-results" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=700" class="alignnone size-large wp-image-1664" src="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=700" alt="build warning" width="700" height="368" srcset="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>and the specific vulnerability on the Repo&#8217;s Advanced Security page:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg"><img loading="lazy" data-attachment-id="1666" data-permalink="https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/4-adv-security/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg" data-orig-size="2214,981" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4-adv-security" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=700" class="alignnone wp-image-1666 size-large" src="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=700" alt="advanced security warning of Microsoft CVE advisory" width="700" height="310" srcset="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/11/21/azure-devops-advanced-security-not-detecting-vulnerabilities-0-components-found/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1656</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/11/vs-vulnerabilities.jpg?w=700" medium="image">
			<media:title type="html">A screenshot from Visual Studio showing NuGet vulnerabilites as Warnings in the Error List.</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/11/2-scanning-fail.jpg?w=700" medium="image">
			<media:title type="html">0 components found</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/11/3-task-results.jpg?w=700" medium="image">
			<media:title type="html">237 components found on NuGet</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/11/3-build-results.jpg?w=700" medium="image">
			<media:title type="html">build warning</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/11/4-adv-security.jpg?w=700" medium="image">
			<media:title type="html">advanced security warning of Microsoft CVE advisory</media:title>
		</media:content>
	</item>
		<item>
		<title>Remove a secret from your local git commit history</title>
		<link>https://mattfrear.com/2024/09/18/remove-a-secret-from-your-local-git-commit-history/</link>
					<comments>https://mattfrear.com/2024/09/18/remove-a-secret-from-your-local-git-commit-history/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Tue, 17 Sep 2024 22:52:32 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[git]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1645</guid>

					<description><![CDATA[I was recently trying to push some code to Azure DevOps, but I was getting an error: $ git push Enumerating objects: 117, done. Counting objects: 100% (107/107), done. Delta compression using up to 12 threads Compressing objects: 100% (66/66), done. Writing objects: 100% (69/69), 10.28 KiB &#124; 1.28 MiB/s, done. Total 69 (delta 42), &#8230; <a href="https://mattfrear.com/2024/09/18/remove-a-secret-from-your-local-git-commit-history/" class="more-link">Continue reading <span class="screen-reader-text">Remove a secret from your local git commit&#160;history</span></a>]]></description>
										<content:encoded><![CDATA[<p>I was recently trying to push some code to Azure DevOps, but I was getting an error:</p>
<pre>$ git push
Enumerating objects: 117, done.
Counting objects: 100% (107/107), done.
Delta compression using up to 12 threads
Compressing objects: 100% (66/66), done.
Writing objects: 100% (69/69), 10.28 KiB | 1.28 MiB/s, done.
Total 69 (delta 42), reused 0 (delta 0), pack-reused 0
remote: Analyzing objects... (69/69) (105 ms)
remote: Validating commits... (5/5) done (2 ms)
remote: Checking for credentials and other secrets... done (906 ms)
error: remote unpack failed: error VS403654: The push was rejected because it contains one or more secrets.
To https://dev.azure.com/xxx/Software/_git/Property.Sync
! [remote rejected] feature/teams-logging -&gt; feature/teams-logging (VS403654: The push was rejected because it contains one or more secrets.

Resolve the following secrets before pushing again. For help, see https://aka.ms/advancedsecurity/secret-scanning/push-protection.

</pre>
<p>Our Azure DevOps repository has GitHub Advanced Security enabled, hence the above error. Pretty cool feature.</p>
<p>The code I&#8217;m pushing doesn&#8217;t have the secret in it anymore &#8211; an early POC commit had the secret in, when I was playing around to see if I could get it to work. But then I removed the secret once I&#8217;d gotten it working.</p>
<p>The <a href="https://learn.microsoft.com/en-us/azure/devops/repos/security/github-advanced-security-secret-scanning?view=azure-devops#what-to-do-if-your-push-was-blocked">suggested fix</a> is to muck around with git rebase and remove the secret from the older commit. Since <em>I don&#8217;t care</em> about intermediate commits in my feature branches, an easier workaround is to squash all commits in the branch, thus removing the secret from the history.</p>
<p>As usual with git, there&#8217;s a million different and confusing ways to do the same thing. I usually go for the simplest method. Here&#8217;s how I did it:</p>
<ol>
<li>create a new branch based off develop and switch to it <code>git checkout -b feature/my-new-branch</code></li>
<li>Squash merge all of the commits in my feature branch into the new branch <code>git merge --squash feature/my-old-branch</code></li>
<li>Commit and push my new branch (so that I can create a pull request into develop branch)</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/09/18/remove-a-secret-from-your-local-git-commit-history/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1645</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;When a Teams webhook request is received&#8221; not working from C# HttpClient</title>
		<link>https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/</link>
					<comments>https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Wed, 11 Sep 2024 01:17:49 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[httpclient]]></category>
		<category><![CDATA[teams]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1636</guid>

					<description><![CDATA[I was recently trying to send a message from my application (an Azure Function) to a Teams channel. The current recommended way (by Microsoft) to do this is via a &#8220;Teams Workflow&#8221;, which is layer over top of Microsoft Power Automate, which is a layer over Logic apps. Here&#8217;s my Teams Workflow: Here&#8217;s the same &#8230; <a href="https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/" class="more-link">Continue reading <span class="screen-reader-text">&#8220;When a Teams webhook request is received&#8221; not working from C#&#160;HttpClient</span></a>]]></description>
										<content:encoded><![CDATA[<p>I was recently trying to send a message from my application (an Azure Function) to a Teams channel.</p>
<p>The current recommended way (by Microsoft) to do this is via a &#8220;Teams Workflow&#8221;, which is layer over top of Microsoft Power Automate, which is a layer over Logic apps.</p>
<p>Here&#8217;s my Teams Workflow:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg"><img loading="lazy" data-attachment-id="1640" data-permalink="https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/workflow/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg" data-orig-size="1231,682" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="workflow" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=700" class="alignnone size-large wp-image-1640" src="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=700" alt="" width="700" height="388" srcset="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=1024 1024w, https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg 1231w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>Here&#8217;s the same Teams Workflow in Power Automate:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg"><img loading="lazy" data-attachment-id="1639" data-permalink="https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/powerautomate/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg" data-orig-size="1003,739" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="powerautomate" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=700" class="alignnone size-large wp-image-1639" src="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=700" alt="" width="700" height="516" srcset="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg 1003w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>Here&#8217;s a slightly different one, which I wrote as an Azure Logic App. Here the first step is &#8220;When a HTTP request is received&#8221;:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg"><img loading="lazy" data-attachment-id="1638" data-permalink="https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/logicapp/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg" data-orig-size="1001,745" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="logicapp" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=700" class="alignnone size-large wp-image-1638" src="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=700" alt="" width="700" height="521" srcset="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg 1001w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>In both cases, I was able to trigger the Power Automate / Logic app fine from Postman, but when I tried from C# code using HttpClient.PostJsonAsync it failed.</p>
<p>The only difference I could see between the Postman request and the HttpClient request was that HttpClient was sending a transfer-encoding=chunked header.</p>
<p>I re-wrote my code to use PostAsync instead, and then it worked fine.</p>
<pre class="brush: csharp; title: ; notranslate">

using HttpClient client = new();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&quot;application/json&quot;));

var card = AdaptiveCard.ExceptionCard(&quot;parcel.changed.v1&quot;, &quot;I800100081376&quot;, &quot;dev&quot;, new InvalidOperationException());

var url = &quot;https://prod-31.australiasoutheast.logic.azure.com:443/workflows/dda945b5337d48....&quot;;

// await client.PostAsJsonAsync(url, card); // this sends a transfer-encoding=chunked header, which Power Automate &amp; Logic Apps doesn&#039;t handle

var json = JsonSerializer.Serialize(card);
var content = new StringContent(json, System.Text.Encoding.UTF8, &quot;application/json&quot;);
await client.PostAsync(url, content);

</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/09/11/when-a-teams-webhook-request-is-received-not-working-from-c-httpclient/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1636</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/09/workflow.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/09/powerautomate.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/09/logicapp.jpg?w=700" medium="image" />
	</item>
		<item>
		<title>Logging to Application Insights with ILogger in Azure functions on .NET 8</title>
		<link>https://mattfrear.com/2024/08/22/logging-to-application-insights-with-ilogger-in-azure-functions-on-net-8/</link>
					<comments>https://mattfrear.com/2024/08/22/logging-to-application-insights-with-ilogger-in-azure-functions-on-net-8/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Thu, 22 Aug 2024 04:12:43 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[azure-function]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1624</guid>

					<description><![CDATA[Today I couldn&#8217;t figure out why any of my ILogger messages in my Azure Function weren&#8217;t appearing in Application Insights. According to my research they should appear as Trace messages. &#160; I tried various Log Level tweaks to host.json to no avail. Fortunately one of my colleagues (hi Ivan!) had previously had the same issue, &#8230; <a href="https://mattfrear.com/2024/08/22/logging-to-application-insights-with-ilogger-in-azure-functions-on-net-8/" class="more-link">Continue reading <span class="screen-reader-text">Logging to Application Insights with ILogger in Azure functions on .NET&#160;8</span></a>]]></description>
										<content:encoded><![CDATA[<p>Today I couldn&#8217;t figure out why any of my ILogger messages in my Azure Function weren&#8217;t appearing in Application Insights. According to my research they should appear as Trace messages.</p>
<pre class="brush: csharp; title: ; notranslate">
logger.LogInformation(&quot;Message ID: {id}&quot;, message.MessageId);
</pre>
<p>&nbsp;</p>
<p>I tried various Log Level tweaks to host.json to no avail.</p>
<p>Fortunately one of my colleagues (hi Ivan!) had previously had the same issue, and he&#8217;d already found the fix, <a href="https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#managing-log-levels">which is documented here.</a></p>
<p>Turns out that dotnet-isolated Functions work a bit differently.</p>
<pre class="brush: csharp; title: ; notranslate">

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices((context, services) =&gt;
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .ConfigureLogging(logging =&gt;
    {
        logging.Services.Configure&lt;LoggerFilterOptions&gt;(options =&gt;
        {
            // https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#managing-log-levels
            // By default, the Application Insights SDK adds a logging filter that instructs the logger to capture only warnings and more severe logs.
            // To disable this behavior, remove the filter rule as part of service configuration:
            var defaultRule = options.Rules.FirstOrDefault(rule =&gt; rule.ProviderName == &quot;Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider&quot;);
            if (defaultRule is not null)
            {
                options.Rules.Remove(defaultRule);
            }
            // Set log level to Information so that we don&#039;t log traces
            var loggingRule = new LoggerFilterRule(&quot;PropertySync&quot;, null, LogLevel.Information, null);
            options.Rules.Add(loggingRule);
        });
    })
    .Build();
</pre>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg"><img loading="lazy" data-attachment-id="1633" data-permalink="https://mattfrear.com/2024/08/22/logging-to-application-insights-with-ilogger-in-azure-functions-on-net-8/appinsights/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg" data-orig-size="1797,669" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="appinsights" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=700" class="alignnone size-large wp-image-1633" src="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=700" alt="azure application insights" width="700" height="261" srcset="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/08/22/logging-to-application-insights-with-ilogger-in-azure-functions-on-net-8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1624</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/appinsights.jpg?w=700" medium="image">
			<media:title type="html">azure application insights</media:title>
		</media:content>
	</item>
		<item>
		<title>A nicer free Blazor WASM Data grid, toast, and confirm</title>
		<link>https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/</link>
					<comments>https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Fri, 16 Aug 2024 03:13:40 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Blazor]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1610</guid>

					<description><![CDATA[A Blazor WASM .NET 8 proof-of-concept project I recently worked needed a data grid. MudBlazor, at the time, it didn&#8217;t support .NET 8 WASM. (It might now, I&#8217;m not sure). Blazorise &#8211; looks good, but I didn&#8217;t want the client to pay, because it&#8217;s a POC. QuickGrid &#8211; used this for the initial version. Easy &#8230; <a href="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/" class="more-link">Continue reading <span class="screen-reader-text">A nicer free Blazor WASM Data grid, toast, and&#160;confirm</span></a>]]></description>
										<content:encoded><![CDATA[<p>A Blazor WASM .NET 8 proof-of-concept project I recently worked needed a data grid.</p>
<ul>
<li><a href="https://github.com/MudBlazor/MudBlazor">MudBlazor</a>, at the time, it didn&#8217;t support .NET 8 WASM. (It might now, I&#8217;m not sure).</li>
<li><a href="https://blazorise.com/">Blazorise</a> &#8211; looks good, but I didn&#8217;t want the client to pay, because it&#8217;s a POC.</li>
<li><a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/components/quickgrid">QuickGrid</a> &#8211; used this for the initial version. Easy to use, but needs CSS skills to customize.</li>
<li><a href="https://www.fluentui-blazor.net/DataGrid">FluentDataGrid</a> &#8211; much prettier, and easier to use than the QuickGrid. Almost a drop-in replacement for the QuickGrid.</li>
</ul>
<h2>QuickGrid</h2>
<p>I initially started out with QuickGrid. After tweaking the CSS to get the column widths right, the result was this:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg"><img loading="lazy" data-attachment-id="1615" data-permalink="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/quickgrid/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg" data-orig-size="2575,1041" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="quickgrid" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=700" class="alignnone size-large wp-image-1615" src="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=700" alt="" width="700" height="283" srcset="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>I would have liked the text to overflow &#8230; and show the full text on hover. I played around with the CSS and it kinda worked, but it wasn&#8217;t great.</p>
<h2>FluentDataGrid</h2>
<p>Later I found the FluentDataGrid, which is part of <a href="https://www.fluentui-blazor.net/">FluentUI Blazor</a>. It already has the overflow with tooltip:</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg"><img loading="lazy" data-attachment-id="1614" data-permalink="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/fluentdatagrid/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg" data-orig-size="2256,939" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="fluentdatagrid" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=700" class="alignnone size-large wp-image-1614" src="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=700" alt="" width="700" height="291" srcset="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<h2>Dialog</h2>
<p>You would think that Blazor would have a built-in easy way to popup a confirm message to the user, but it doesn&#8217;t come with any. The only way I could find was to use an old-fashioned javascript confirm:</p>
<pre class="brush: csharp; title: ; notranslate">

bool confirmed = await JsRuntime.InvokeAsync&lt;bool&gt;(&quot;confirm&quot;, $&quot;Are you sure you want to resend {loggedEvent.MessageBody}?&quot;);
if (confirmed)
{

// do stuff

</pre>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg"><img loading="lazy" data-attachment-id="1618" data-permalink="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/confirm/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg" data-orig-size="2307,1110" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="confirm" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=700" class="alignnone size-large wp-image-1618" src="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=700" alt="" width="700" height="337" srcset="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>Which is pretty basic.</p>
<p>FluentUI Blazor&#8217;s dialog is a bit prettier:</p>
<pre class="brush: csharp; title: ; notranslate">

var dialog = await _dialogService.ShowConfirmationAsync($&quot;Are you sure you want to resend {loggedEvent.EventType} for {loggedEvent.Id}?&quot;);
var result = await dialog.Result;

if (!result.Cancelled)
{

// do stuff

</pre>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg"><img loading="lazy" data-attachment-id="1620" data-permalink="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/fluentconfirm/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg" data-orig-size="2254,942" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="fluentconfirm" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=700" class="alignnone size-large wp-image-1620" src="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=700" alt="" width="700" height="293" srcset="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<h2>Notifications</h2>
<p>FluentUI Blazor also has a ToastService for easily showing a pop-up (like how toast pops-up when it&#8217;s ready) to notify users.</p>
<pre class="brush: csharp; title: ; notranslate">

_toastService.ShowSuccess($&quot;{loggedEvent.Id} was resent.&quot;);

</pre>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg"><img loading="lazy" data-attachment-id="1622" data-permalink="https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/toast/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg" data-orig-size="2242,942" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="toast" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=700" class="alignnone size-large wp-image-1622" src="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=700" alt="" width="700" height="294" srcset="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/08/16/a-nicer-free-blazor-wasm-data-grid-toast-and-confirm/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1610</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/quickgrid.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/fluentdatagrid.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/confirm.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/fluentconfirm.jpg?w=700" medium="image" />

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/08/toast.jpg?w=700" medium="image" />
	</item>
		<item>
		<title>HttpTrigger Azure Functions timeout</title>
		<link>https://mattfrear.com/2024/08/01/httptrigger-azure-functions-timeout/</link>
					<comments>https://mattfrear.com/2024/08/01/httptrigger-azure-functions-timeout/#respond</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Thu, 01 Aug 2024 05:08:24 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[azure-function]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1604</guid>

					<description><![CDATA[Here&#8217;s an annoying bug I had today. I have an Azure Function which contains both [ServiceBusTrigger] and [HttpTrigger] functions. My HttpTrigger were timing out while debugging locally, for some mysterious reason. It turned out the problem was that I had added a comment to my function&#8217;s host.json. Unfortunately that breaks things completely. GitHub issue here.]]></description>
										<content:encoded><![CDATA[<p>Here&#8217;s an annoying bug I had today. I have an Azure Function which contains both [ServiceBusTrigger] and [HttpTrigger] functions. My HttpTrigger were timing out while debugging locally, for some mysterious reason.</p>
<p>It turned out the problem was that I had added a comment to my function&#8217;s host.json. Unfortunately that breaks things completely.</p>
<p>GitHub issue <a href="https://github.com/Azure/azure-functions-host/issues/9583#issuecomment-2262036574">here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/08/01/httptrigger-azure-functions-timeout/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1604</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>
	</item>
		<item>
		<title>Add authentication to an Azure Static Web App&#8217;s API</title>
		<link>https://mattfrear.com/2024/05/08/authentication-azure-static-web-app-api/</link>
					<comments>https://mattfrear.com/2024/05/08/authentication-azure-static-web-app-api/#comments</comments>
		
		<dc:creator><![CDATA[mattfrear]]></dc:creator>
		<pubDate>Wed, 08 May 2024 04:22:30 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[azure-function]]></category>
		<guid isPermaLink="false">http://mattfrear.com/?p=1555</guid>

					<description><![CDATA[At my current client we are writing a Blazor WASM app which is deployed as a Static Web App. The backend is an Azure Function which is deployed as a &#8220;Bring your own&#8221; function, however I think this still applies if the backend is a Managed Function. The static web app is hosted in Azure &#8230; <a href="https://mattfrear.com/2024/05/08/authentication-azure-static-web-app-api/" class="more-link">Continue reading <span class="screen-reader-text">Add authentication to an Azure Static Web App&#8217;s&#160;API</span></a>]]></description>
										<content:encoded><![CDATA[<p>At my current client we are writing a Blazor WASM app which is deployed as a Static Web App. The backend is an Azure Function which is deployed as a <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/functions-bring-your-own">&#8220;Bring your own&#8221; function</a>, however I think this still applies if the backend is a <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/apis-functions">Managed Function</a>.</p>
<p>The static web app is hosted in Azure at <a href="https://calm-ocean.33.azurestaticapps.net/" rel="nofollow">https://calm-ocean.33.azurestaticapps.net/</a>. All of it&#8217;s <a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-microsoft-entra-id">pages are protected with OAuth</a> on Microsoft Entra ID (formerly Azure AD).</p>
<p>The API is an Azure function with an HTTP endpoint at say <a href="https://my-func.azurewebsites.net/api/blogs" rel="nofollow">https://my-func.azurewebsites.net/api/blogs</a>.</p>
<p>At first this endpoint had no authentication, meaning it can be called directly and return a 200.</p>
<p>I then <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/functions-bring-your-own#link-the-azure-functions-app-to-the-static-web-apps-resource">linked the Static Web App to the Azure function</a>, which adds an &#8220;Azure Static Web Apps&#8221; Identity provider to the Azure Function, which means only the Static Web app can call the Function.</p>
<p><a href="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg"><img loading="lazy" data-attachment-id="1559" data-permalink="https://mattfrear.com/2024/05/08/authentication-azure-static-web-app-api/azurefunction/#main" data-orig-file="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg" data-orig-size="1773,847" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="azurefunction" data-image-description="" data-image-caption="" data-medium-file="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=300" data-large-file="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=700" class="alignnone size-large wp-image-1559" src="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=700&#038;h=334" alt="Azure portal screenshot" width="700" height="334" srcset="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=700 700w, https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=1400 1400w, https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=150 150w, https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=300 300w, https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=768 768w, https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=1024 1024w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
<p>After linking, if I try call my function endpoint at <a href="https://my-func.azurewebsites.net/api/blogs" rel="nofollow">https://my-func.azurewebsites.net/api/blogs</a> it now returns a 400 (it should probably return a 401).</p>
<h2>The security hole</h2>
<p>The Static Web App (<a href="https://calm-ocean.33.azurestaticapps.net/" rel="nofollow">https://calm-ocean.33.azurestaticapps.net/</a>) proxies any calls to the function&#8217;s endpoints at <a href="https://calm-ocean.33.azurestaticapps.net/api" rel="nofollow">https://calm-ocean.33.azurestaticapps.net/api</a>.</p>
<p>This means that by default, unauthenticated users can still call the API but via the Static Web App, i.e. <a href="https://calm-ocean.33.azurestaticapps.net/api/blogs" rel="nofollow">https://calm-ocean.33.azurestaticapps.net/api/blogs</a> &#8211; even though all other pages are protected by OAuth! Which is a big security hole <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f631.png" alt="😱" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>The fix</h2>
<p>The fix is quite simple. Specify that <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#restrict-access-to-entire-application">all routes should be locked down in the</a> staticwebapp.config.json file (except our Blazor authentication pages):</p>
<pre class="brush: jscript; title: ; notranslate">
{
 &quot;routes&quot;: [
    {
      // Our Blazor pages have authentication via the [Authorize] attribute (in _Imports.razor).
      // Blazor&#039;s auth routes are at authentication/*, so allow anonymous access to them.
      // FYI, Azure Static Web App&#039;s built-in auth is at .auth/
      &quot;route&quot;: &quot;authentication/*&quot;,
      &quot;allowedRoles&quot;: [ &quot;anonymous&quot; ]
    },
    {
      // Our API is an Azure function which is proxied on the &quot;api&quot; route. We don&#039;t want to allow anonymous access! We need to specify that calls to api/* are authenticated.
      // Let&#039;s lock down the whole site, so that requests to any page will need SWA auth, which is then passed on to our api/* calls.
      &quot;route&quot;: &quot;/*&quot;,
      &quot;allowedRoles&quot;: [ &quot;authenticated&quot; ]
    }
  ],
  &quot;responseOverrides&quot;: {
    &quot;401&quot;: {
      &quot;statusCode&quot;: 302,
      &quot;redirect&quot;: &quot;/.auth/login/aad&quot;
    }
  }
}
</pre>
<p>Once deployed to Azure, if you try call the API directly (i.e. in an incognito browser window), you&#8217;ll be redirected to login.<br />
One obvious gotcha is that this won&#8217;t work when you&#8217;re debugging locally, because your local function will be on a completely different port and isn&#8217;t proxied.</p>
<p><strong>Pro tip</strong>: if you&#8217;re having trouble getting this to work, you can navigate to /.auth/me on your Static Web App to see the information about the currently logged in user. If you don&#8217;t see anything then you can sign in at <code>/.auth/login/aad</code>. These <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/authentication-authorization">.auth routes</a> are built-in to Azure Static Web Apps.</p>
<p>PS. after figuring all this out, I found this page which is a thorough treatment of how to combine <a href="https://medium.com/@manuelspinto/shared-authentication-in-azure-static-web-apps-using-only-net-blazor-and-c-functions-003dfed7047c">Azure Static Web App&#8217;s authentication with Blazor WASM</a>. Personally I haven&#8217;t needed to go that far myself &#8211; I&#8217;m so far only using the guides I&#8217;ve linked to above to do Blazor authentication.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mattfrear.com/2024/05/08/authentication-azure-static-web-app-api/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1555</post-id>
		<media:content url="https://0.gravatar.com/avatar/f0158578a64e4ad77ae0358305669575e4651e11a6058601272055021d464678?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="https://mattfrear.com/wp-content/uploads/2024/05/azurefunction.jpg?w=700" medium="image">
			<media:title type="html">Azure portal screenshot</media:title>
		</media:content>
	</item>
	</channel>
</rss>
