<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>IIS Field Readiness - blog of the European IIS team</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/friis/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/friis/feed.xml</link>
    <description>This blog deals with troubleshooting IIS and ASP.net as well as web related technologies in production environments - tips and tricks on development and product updates</description>
    <lastBuildDate>Fri, 20 Apr 2018 09:46:19 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>How to find the Global Admin for your Azure AD tenant</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/how-to-find-the-global-admin-for-your-azure-ad-tenant</link>
      <pubDate>Fri, 20 Apr 2018 11:46:19 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3495</guid>
      <description><![CDATA[The smooth working of a bot will require a proper configuration on Azure AD. Sometimes users...]]></description>
      <content:encoded><![CDATA[The smooth working of a bot will require a proper configuration on Azure AD. Sometimes users themselves don't have the permission to modify settings in AAD, only Global Admin will have the right, then the question becomes: how to find my Global Admin ? For now it's not feasible via Azure Portal, but we can user Powershell commands to achieve this goal.
<p style="background: white">Here we'll use the <strong>Azure Active Directory PowerShell for Graph</strong> module. It can be downloaded and installed from the PowerShell Gallery: www.powershellgallery.com. The gallery uses the PowerShellGet module. The PowerShellGet module requires <strong>PowerShell 3.0 or newer </strong>and requires <strong>one of the following operating systems</strong>:</p>
<p style="background: white">Windows 10 / Windows 8.1 Pro / Windows 8.1 Enterprise / Windows 7 SP1 / Windows Server 2016 TP5 / Windows Server 2012 R2 / Windows Server 2008 R2 SP1</p>
<p style="background: white">PowerShellGet also requires <strong>.NET Framework 4.5 or above</strong>. You can install .NET Framework 4.5 or above from <a href="https://www.microsoft.com/en-us/download/details.aspx?id=30653">here</a>. For more information, please refer to <a href="https://msdn.microsoft.com/powershell/gallery/readme">this link</a>. For more detailed info on installation of the AzureAD cmdlets please see: <a href="https://docs.microsoft.com/en-us/powershell/azuread/">Azure Active Directory Powershell for Graph</a>.</p>
<p style="background: white">1. Launch Windows Powershell console as Administrator;</p>
2. If you have never installed Azure AD module in Powershell, please type "<span style="font-family: Consolas;font-size: 10pt;background-color: #e7e6e6">Install-Module AzureAD</span>";

3. You'll receive the following warning:

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/042018_0942_Howtofindth1.png" />

4. Type Y to continue; or you can type A to accept all so you'll not be asked again;

5. Once installation finished, type command "<span style="font-family: Consolas;font-size: 10pt;background-color: #e7e6e6">Connect-AzureAD</span>", a pop-up window for user connection will show up. Please logon with your Azure account;

6. Once you get logged in, some basic information regarding this AAD tenant will be shown in Powershell console:

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/042018_0942_Howtofindth2.png" />

7. Then execute the command "<span style="font-family: Consolas;font-size: 10pt;background-color: #e7e6e6">Get-AzureADDirectoryRole</span>", a list of available roles under this AAD tenant will be shown;

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/042018_0942_Howtofindth3.png" />

8. From the list, copy the <strong>ObjectId</strong> for the fole "<span style="font-family: Consolas;font-size: 10pt;background-color: #e7e6e6">Company Administrator</span>" into Notepad; (<span style="text-decoration: underline"><strong>Note</strong></span>: Global Administrator = Company Administrator in this context)

9. Then execute the following command to get the Admin account info (please replace the highlighted part with the ObjectId you've copied in Step 8):

<span style="font-family: Consolas;font-size: 10pt"><span style="background-color: #e7e6e6">Get-AzureADDirectoryRoleMember -ObjectId "</span><span style="background-color: yellow"><em>Put-ObjectId-here</em></span><span style="background-color: #e7e6e6">"</span></span>

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/042018_0942_Howtofindth4.png" />

10. You'll get some necessary information from the displayed result regarding your Global Admin.

Hope this article would be useful for you.

Jin W. from Microsoft France IIS/ASP.NET/Azure Bot team

<em>You might also be interested in:
</em>

<em>Administrator roles in Azure Active Directory
</em>

<a href="https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal">https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal</a>

<em>Azure Active Directory PowerShell 2.0
</em>

<a href="https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0">https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0</a>]]></content:encoded>
    </item>
    <item>
      <title>Fail to create bot with error ‘Authorization_RequestDenied’</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/fail-to-create-bot-with-error-authorization_requestdenied</link>
      <pubDate>Wed, 04 Apr 2018 22:09:12 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3435</guid>
      <description><![CDATA[Since last December our team starts to support Azure Bot Framework, so in this blog you'll start...]]></description>
      <content:encoded><![CDATA[Since last December our team starts to support Azure Bot Framework, so in this blog you'll start seeing some best practices from our field experience

Many of our customers encounter the following error when creating a bot in Azure Bot portal (please <a href="https://docs.microsoft.com/en-us/bot-framework/bot-service-quickstart">check here for bot creation steps</a>):

<strong>"Authorization_RequestDenied
</strong>

<strong>Insufficient privileges to complete the operation. Please check that your account has sufficient access to the Microsoft app registration portal link below.</strong> "

This is a known issue which is often caused by insufficient permission of the user account in Azure AD. Basically there are 2 settings to verify if the account has appropriate permissions:

In Azure portal, go to Azure Active Directory -&gt; click on "<strong>User Settings</strong>" -&gt; verify the following values:
<ul>
 	<li>Under "<strong>App registrations</strong>" section, "<strong>Users can register applications</strong>" should be "<strong>Yes</strong>";</li>
 	<li>If your account is a guest user, then under "<strong>External users</strong>" section, "<strong>Guest users permissions are limited</strong>" should be set to "<strong>No</strong>".</li>
</ul>
<img alt="" src="image002.jpg@01D39490.BDD3C450" /><a href="https://msdnshared.blob.core.windows.net/media/2018/04/AADUserSettings.png"></a><a href="https://msdnshared.blob.core.windows.net/media/2018/04/AADUserSettings.png"></a><a href="https://msdnshared.blob.core.windows.net/media/2018/04/AADUserSettings.png"><img width="1024" height="350" class="alignnone wp-image-3445 size-large" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/AADUserSettings-1024x350.png" /></a>

You may find that you are not able to modify those settings, that's because they are managed by Global Admin accounts for this AD tenant.

Please contact your Global Admin account to implement the right settings.

Another situation you may encounter is, you don't have access to the "<strong>User settings</strong>" page with message "<strong>No access</strong>":

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/04/040418_2009_Failtocreat1.png" />

This is probably because you are a guest user with a custom domain in this Azure AD tenant, and action plan is the same: <strong>reach out to your Global Admin asking for permission check</strong>.

If this cannot resolve your problem, please don't hesitate to raise a support ticket so we can work together on it.

We'll continue sharing our knowledge about Azure Bot Framework, stay tuned and let's Bot together!

<em>Some articles you may be interested in:
</em>

<em>Migrate your bot from Bot Framework Portal to Azure Portal
</em>

<a href="https://docs.microsoft.com/en-us/bot-framework/bot-service-migrate-bot">https://docs.microsoft.com/en-us/bot-framework/bot-service-migrate-bot</a>

<em>Debug bots with Bot Framework Emulator
</em>

<a href="https://docs.microsoft.com/en-us/bot-framework/bot-service-debug-emulator">https://docs.microsoft.com/en-us/bot-framework/bot-service-debug-emulator</a>

Jin W. from Microsoft Support team of IIS/ASP.NET/Azure Bot]]></content:encoded>
    </item>
    <item>
      <title>Issues with managing Bot Registration Properties</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/issues-with-managing-bot-registration-properties</link>
      <pubDate>Mon, 05 Mar 2018 12:43:01 GMT</pubDate>
      <dc:creator><![CDATA[u014_delatrei]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3405</guid>
      <description><![CDATA[I've seen quite a few questions recently about issues managing the Bot Registration properties....]]></description>
      <content:encoded><![CDATA[I've seen quite a few questions recently about issues managing the Bot Registration properties. While working with the Bot Services, you might need to make some changes to the properties, such as generating a new password or adding a Co-owner to the Bot. You can edit the Bot Registration properties by going to the <span style="font-family: Times New Roman;font-size: 12pt"><strong>Settings</strong></span> blade, and then to <span style="font-family: Times New Roman;font-size: 12pt"><strong>Manage</strong></span> link, next to the <span style="font-family: Times New Roman;font-size: 12pt"><strong>Microsoft App ID</strong></span>. These steps are also outlined in the documentation for how to register a bot with Bot Service <a href="https://docs.microsoft.com/en-us/bot-framework/bot-service-quickstart-registration">https://docs.microsoft.com/en-us/bot-framework/bot-service-quickstart-registration</a>

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/022718_1856_Issueswithm1.png" width="616" height="456" class="" />

<span style="color: black">When you click on the <strong>Manage</strong> link, it should open up the Registration properties on <a href="https://apps.dev.microsoft.com">https://apps.dev.microsoft.com</a>, where you can manage the App Password, the Platform, the Owners, the Permissions, etc.<em> </em></span>

If you don't have the right permissions to manage the Bot Registration properties, you will see an error message, saying "The application was not found. The application no longer exists, or is not associated with your account."

<img alt="" src="https://msdnshared.blob.core.windows.net/media/2018/02/022718_1856_Issueswithm2.png" width="813" height="237" class="" />

However, it's not clear from the error message what permissions you are missing to be able to manage the Registration properties. If you believe that you should have the necessary permissions, but still see the above error message, you might be in the following scenario:
<ol>
 	<li>You have access to more than one tenant AND</li>
 	<li>You are creating the bot in a tenant that is not your default (The default tenant is the one that is automatically selected when you first sign into Azure in an incognito window.)</li>
</ol>
<span style="color: #333333">If the two conditions above are met, you will see the error message when trying to manage the Bot Registration properties because it is not possible to manage application registrations that are not in the user's default tenant.</span>

<span style="color: #333333">The challenge here is that</span> there is no way of changing the default tenant in Azure, at least for now. This feature might be added in the future, but until then the workaround you may pursue is the following:
<ul>
 	<li>Browse the apps.dev.microsoft.com logged in with the application owner account</li>
 	<li>Try to see if you can force the URL to reach the application: <a href="https://apps.dev.microsoft.com/#/application&lt;app id&gt;">https://apps.dev.microsoft.com/#/application/&lt;app id&gt;</a></li>
 	<li>
<div>Test the same URL but this time logged in as the Global Admin of the directory.</div></li>
</ul>
You should be able to manage the Bot Registration properties using the above workaround while logged in as application owner or Global Admin of the directory.

For creating other bots in the future, another possibility is to set up an account that is only in the default tenant, and use that to create the bot.

Hope that you've found this article helpful. This blog will continue to add more content related to the Bot Framework.

For more Bot Framework content, also check out this blog: <a href="https://blog.botframework.com/"><span>https://blog.botframework.com/</span></a>

If you have a question that is not answered in one of the blog articles, don't hesitate to open a support ticket with Microsoft.

&nbsp;

By Roxana Gheorghe]]></content:encoded>
    </item>
    <item>
      <title>Logging for ASP.net CORE applications when you receive 502.3 and 500 status codes</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/logging-for-asp-net-core-applications-when-you-receive-502-3-and-500-status-codes</link>
      <pubDate>Wed, 07 Feb 2018 10:27:09 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3305</guid>
      <description><![CDATA[As we start to see more and more ASP.net Core applications being used in production, our customers...]]></description>
      <content:encoded><![CDATA[<span style="color: #44546a">As we start to see more and more ASP.net Core applications being used in production, our customers are coming to us with problems that are specific to these types of deployment scenarios. This article will attempt to deal with one such scenario – where the ASP.net Core web-application running behind IIS is sending back 502.3 response codes or simply 500 response codes.
</span>

<span style="color: #c00000"><strong>IIS and ASP.net Architecture lesson.
</strong></span>

<span style="color: #44546a">Before we delve into the topic, a small architecture refresher is always nice to have. With ASP.net running on the full .Net framework, the .Net Runtime was hosted inside the IIS worker process, and all execution and response elaboration took place here. The diagram below attempts to show that:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2018/02/020118_1148_LoggingforA1.png" alt="" />
<ol>
 	<li><span style="color: #44546a">The client computer (browser or application) will create and send an HTTP request to a web-server (which in our case is IIS)
</span></li>
 	<li><span style="color: #44546a">The http.sys driver (kernel component of IIS) receives the request and queues for processing in the worker process (user mode component)
</span></li>
 	<li><span style="color: #44546a">Once finished processing, the worker process has elaborated an HTTP response for the request, an sends it back to http.sys
</span></li>
 	<li><span style="color: #44546a">Http.sys sends the response back across the wire, to the requesting client.
</span></li>
</ol>
<span style="color: #44546a">Should you need a complete refresher of the IIS architecture, I would suggest the IIS architecture and components video series available here: <a href="https://linqto.me/n/IISArchitecture">https://linqto.me/n/IISArchitecture</a></span> .

<span style="color: #44546a">In the case of an ASP.net Core web-application that works behind an IIS web-server, the application runs in its own process, called dotnet.exe. This process is activated when the request is received by the worker process, and the dotnet.exe process is a child process of the w3wp.exe process. Let's see the architecture:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2018/02/020118_1148_LoggingforA2.png" alt="" />

<span style="color: #44546a">With ASP.net Core request processing, the request follows the same path to the Worker process, so we will only focus on the different steps:
</span>

<span style="color: #44546a">3 – the ANCM (short for ASP.net Core Module) is a native module that lives inside the worker process, and will start the dotnet.exe process and then forward the request to it for processing.
</span>

<span style="color: #44546a">4- the ASP.net Core application that lives inside dotnet.exe (child process of w3wp.exe) will process the request and issue a response.
</span>

<span style="color: #44546a">This architecture should look pretty familiar to some since it resembles CGI (common gateway interface) execution for languages like Perl and Php in IIS, however the dotnet.exe process is not restarted after executing each request.
</span>

<span style="color: #c00000"><strong>Causes of 502.3 responses for ASP.net Core applications
</strong></span>

<span style="color: #44546a">If we review the Http status and substatus codes for IIS (available here: <a href="https://linqto.me/IISCodes">https://linqto.me/IISCodes</a></span>), <span style="color: #44546a">the 502.3 status code translates into: Bad Gateway: Forwarder Connection Error. The gateway in this case is the IIS worker process, since this is working as a reverse proxy between the connecting client and the dotnet.exe process. In plain English, when you see this status code in the IIS logs, it means that the dotnet.exe process either did not respond to the request or took too long to respond (step 3 in the above diagram).
</span>

<span style="color: #44546a">Using <a href="https://docs.microsoft.com/en-us/iis/troubleshoot/using-failed-request-tracing/troubleshooting-failed-requests-using-tracing-in-iis">FREB tracing</a>, is such cases does not yield many more details. You will only see that the status code of the request is changed by the ANCM module but will not have any information as to what occurred in the dotnet.exe process, which can be a challenge.
</span>

<span style="color: #44546a">The first thing you need to know is that the ANCM module does expose configuration in IIS. While not available under an Icon in the central pane of the IIS Manager, this configuration can be reached by using the configuration manager feature in the IIS manager, and then going into the <strong>system.WebServer/AspNetCore</strong> tag as shown below:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2018/02/020118_1148_LoggingforA3.png" alt="" />

<span style="color: #44546a">Settings available for the ANCM </span>:
<img src="https://msdnshared.blob.core.windows.net/media/2018/02/020118_1148_LoggingforA4.png" alt="" />

<span style="color: #44546a">Some settings to call out here are the following:
</span>
<ul>
 	<li><span style="color: #44546a">Start-up time limit: the allowed limit for the dotnet.exe process to start and begin processing requests. The default value is 120 seconds.
</span></li>
 	<li><span style="color: #44546a">Shutdown time limit: when the worker process shuts down for recycling, it will have to await the shutdown of the dotnet.exe process before it performs a shutdown of its own. This time is by default 10 seconds.
</span></li>
 	<li><span style="color: #44546a">Request timeout: the amount of time that the ANCM is willing to wait for the dotnet.exe process to process an HTTP request it has been forwarded. Should this time be exceeded, the ANCM module will return a 502.3 response code.
</span></li>
</ul>
<span style="color: #c00000"><strong>How to gather more data – logging
</strong></span>

<span style="color: #44546a">The ANCM module also provides the possibility to turn on logging for the ASP.net Core application. This can be done by setting the value of <strong>stdoutLogEnaled</strong> to 'true' and. The tricky part is that the <strong>Logs </strong>folder (default value of the <strong>stdoutLogFile</strong>) has to be created by hand, if not no logs will be generated. As such, you will need to bring up File Explorer, navigate to the root folder for your ASP.net Core website (such as C:\inetpub\wwwroot) and create a folder called '<strong>Logs</strong>' inside.
</span>

<span style="color: #44546a">You can also control the level of verbosity for the logs. This is done inside the appsettings.json file in which you have the following configuration section:
</span>
<p style="background: #d9d9d9"><span style="font-family: Courier New;font-size: 9pt">"Console": {
"LogLevel": {
<span style="color: red"><strong>       "Default": "Warning"</strong></span>
}
}
</span></p>
<span style="color: #44546a">By default, the level is set to 'Warning' and all first hand exceptions and critical errors will be logged. If you set the logging level to 'Information' everything, including the request Urls will be logged. Below is an excerpt from one such log show that a new request has arrived for processing:
</span>
<p style="background: #d9d9d9"><span style="font-family: Courier New;font-size: 9pt">info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting <span style="color: red"><strong>HTTP/1.1 OPTIONS https://corewebapi/api/EchoCors</strong></span>
</span></p>
<span style="color: #44546a">You can see you have information on the Request verb used, the url and protocol version.
</span>

<span style="color: #44546a">When trying to understand why your application is not behaving as expected, using logging to review errors in execution in this way can provide you with vital clues for troubleshooting. In <a href="https://blogs.msdn.microsoft.com/friis/2017/11/24/setting-up-cors-request-with-windows-integrated-authentication-and-asp-net-core/">the ASP.net Core WebAPI CORS tutorial</a> I have written on this blog, this technique proved invaluable for debugging the WebAPI application while writing the tutorial.
</span>

<span style="color: #333333;font-family: Segoe UI;font-size: 10pt">By <strong>Paul Cociuba</strong>
<a href="https://linqto.me/about/pcociuba">https://linqto.me/about/pcociuba</a></span>]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET HttpContext in async/await patterns using the Task Parallel Library – Part 3</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-3</link>
      <pubDate>Tue, 05 Dec 2017 16:50:41 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3196</guid>
      <description><![CDATA[The SynchronizationContext (SC) is a vital component for the ASP.NET request lifecycle and it is...]]></description>
      <content:encoded><![CDATA[The SynchronizationContext (SC) is a vital component for the ASP.NET request lifecycle and it is strictly coupled to the HttpContext. In the <a href="https://blogs.msdn.microsoft.com/friis/2017/12/02/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-1/">previous posts</a> we saw how running asynchronous operations by using specific TPL patterns might lead to losing the SynchronizationContext and, thus, reference to the HttpContext.

Such a behavior can impact applications in several ways, both directly (e.g. tasks failing due to null references when accessing the HttpContext or one of its fields) and indirectly (e.g. faults in external libraries).

&nbsp;

Before jumping to the summary and conclusions, I owe you an answer to the challenge from the <a href="https://blogs.msdn.microsoft.com/friis/2017/12/02/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-2/">previous post</a>.

Below the question I left you to meditate upon, which refers to our demo MVC application used to output debug traces about the execution flow and the SC flow status (I encourage you to quickly re-check the previous posts to recall the code involved):

&nbsp;
<p style="text-align: left"><em>What do you expect to happen when calling the Index action with</em></p>

<ul>
 	<li style="text-align: left"><em>configureAwait = false</em></li>
 	<li>
<p style="text-align: left"><em>tsFromSyncContext = true</em></p>
</li>
</ul>
&nbsp;

Previously we went through some tests and analyzed what happens when turning those flags on and off individually. Specifically:
<ul>
 	<li><em>configureAwait</em> set to <em>false</em> causes the SC to stop flowing starting from the very first await operation. This yields into a definitive loss of the SC, which is then unavailable both in the awaited task and in the awaiter context once it resumes the execution.</li>
 	<li><em>tsFromSyncContext</em> set to <em>true</em>, instead, proved to be useful to persist the SC on the awaited task.</li>
</ul>
&nbsp;

This is the output we get when running the application with both flags enabled.

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part3-0.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part3-0.png" alt="" class="alignnone size-full wp-image-3205" width="587" height="672" /></a>

Notice the second await operation (the one calling <em>Task.Factory.StartNew</em>) fails. The error message is somewhat cryptic. However if we speculate on what the consequences of calling <em>ConfigureAwait(false)</em> on the awaiter context are, we should understand the SC is lost once the execution is returned to the controller context. Therefore, when the second await operation is invoked and tries to post the newly created task against the current SC, the operation simply can't happen as there is no SC available any more.

&nbsp;

If you followed me thus far, this example should point out how delicate this whole system could be and how the TPL primitives could be challenging to handle and lead to unexpected behaviors.

<hr />

<h2>Wrapping it all up!</h2>
Up to this point, I hope we have a clearer vision on the various scenarios we can run into when using async/await patterns in ASP.NET. However, I bet there are still a few questions open. The most interesting ones, or better, the ones I would be asking myself are:
<ul type="disc">
 	<li>Why awaiting on <em>Task.Run</em> (or other primitives like <em>Task.Factory.StartNew</em>) does not persist the SC while awaiting on a custom async method does?</li>
 	<li>Why if we force the awaiter to use the <em>SynchronizationContextTakScheduler</em> we don't face this problem?</li>
 	<li>Avoiding primitive TPL APIs might just not be a feasible option. How can we deal with this situation and instrument a workaround?</li>
</ul>
Let's try to address them one by one.

&nbsp;
<h4>Why awaiting on <em>Task.Run</em> does not persist the SC while awaiting a custom async method does?</h4>
To find out, we need to peek at the .NET source code. Luckily, <a href="https://referencesource.microsoft.com/">it's public</a>! :)

<em>Task.Run </em>and other primitive TPL methods rely on the internal method <strong><em>Task.InternalStartNew</em></strong>, which then calls into the <a href="https://referencesource.microsoft.com/mscorlib/system/threading/Tasks/Task.cs.html#28d15da46451586a">following one</a>:

[code highlight="9" language="csharp"]
internal void PossiblyCaptureContext(ref StackCrawlMark stackMark) {
	// In the legacy .NET 3.5 build, we don't have the optimized overload of Capture()
	// available, so we call the parameterless overload.
#if PFX_LEGACY_3_5
	CapturedContext = ExecutionContext.Capture();
#else
	CapturedContext = ExecutionContext.Capture(
		ref stackMark,
		ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase);
#endif
}
[/code]

The <a href="https://index/?query=task.run&amp;rightProject=mscorlib&amp;file=system%5Cthreading%5Cexecutioncontext.cs&amp;rightSymbol=zaetx5kq4krx">Capture</a> method, invoked with the <strong>IgnoreSyncCtx</strong> flag, does exactly what we would expect. It skips capturing the SC, suppressing its flow.

[code highlight="2" language="csharp"]
// capture the sync context
if (0 == (options &amp; CaptureOptions.IgnoreSyncCtx))
 syncCtxNew = (ecCurrent.SynchronizationContext == null) ? null : ecCurrent.SynchronizationContext.CreateCopy();
[/code]

Guess what? The framework doesn't let user-defined async methods to follow this very same path and simply lets the SC flow.
What this actually means is if in our code we simply run await on DoStuff, the SC never gets lost.

&nbsp;
<h4>Why if we force the awaiter to use the SynchronizationContextTakScheduler we don't lose the SC?</h4>
This question also needs some internals lookup.

The <em>SyncrhonizationContextTaskScheduler</em> exposes a <a href="https://referencesource.microsoft.com/mscorlib/system/threading/Tasks/TaskScheduler.cs.html#3f429661d74bea22">queueing mechanism</a> that posts the work items against the currently captured SC. In this way, the SC keeps flowing and it is persisted.

[code highlight="3" language="csharp"]
protected internal override void QueueTask(Task task)
{
	m_synchronizationContext.Post(s_postCallback, (object)task);
}
[/code]

On the contrary, the ThreadPoolTaskScheduler (default for ASP.NET), ignores the SC completely:

[code highlight="14" language="csharp"]
protected internal override void QueueTask(Task task)
{
	if ((task.Options &amp; TaskCreationOptions.LongRunning) != 0)
	{
		// Run LongRunning tasks on their own dedicated thread.
		Thread thread = new Thread(s_longRunningThreadWork);
		thread.IsBackground = true; // Keep this thread from blocking process shutdown
		thread.Start(task);
	}
	else
	{
		// Normal handling for non-LongRunning tasks.
		bool forceToGlobalQueue = ((task.Options &amp; TaskCreationOptions.PreferFairness) != 0);
		ThreadPool.UnsafeQueueCustomWorkItem(task, forceToGlobalQueue);
	}
}
[/code]

<h4></h4>
<h4>Avoiding primitive TPL APIs might just not be a feasible option. How can we deal with this situation and instrument a workaround?</h4>
Eventually if we just cannot get rid of calling <em>Task.Run</em>, what can we do?

The best option is to plan for stateless asynchronous operations. If you think about it, the great advantage of async/await is to offload background operations and allow the request to keep on executing in the meantime. Making those tasks stateless not only solves the potential problem of losing the <em>HttpContext</em>, but it also makes the web application more robust in case a background operation fails.
Odds of a ASP.NET request really needing to await on a purely stateless operation are not many and should let you think twice whether background operations are worth to be made asynchronous at all, given they would still have to be awaited for the request to complete.
Last but not least if you are thinking of porting your web app on microservices for great scaling and orchestration (e.g. deploying it on a Azure Service Fabric cluster), stateless agents performing specific, request-agnostic tasks can be much easier to implement.

That said, there might be situations where going stateless is not possible or easily achievable. Similarly there certainly are scenarios where an ASP.NET request should await on an async operation.
For such situations, the most immediate approach is either to await on custom async methods (which do not lead to SC loss) or on new tasks by using the <em>Task.Factory.StartNew</em> overload accepting a <em>TaskScheduler</em> as parameter. In other words, this would mean overwriting all code references from

[code gutter="false" language="csharp"]
Await Task.Run(myBackgroundDelegate());
[/code]

To

[code gutter="0" language="csharp"]
Await Task.Factory.StartNew(myBackgroundDelegate(),
CancellationToken.None,
TaskCreationOptions.RunContinuationsAsynchronously,
TaskScheduler.FromCurrentSynchronizationContext());
[/code]

Unfortunately, this approach might not fit all the situations too. For instance what if <em>Task.Run</em> is used in an external library?
In such a scenario, there is actually one an additional "trick" we can use. The caveat is to await on a wrapper task, that manually posts the actual awaitable operation against the SC.

To grasp how this works a little better, let's see it applied to our very first example using the Context action of the Home controller.
Besides the code for storing the SC I added a new log line to show if the SC context is properly restored once the execution resumes on the controller context:

[code highlight="7, 11-17, 19" language="csharp"]
public async Task&lt;ActionResult&gt; Context()
{
	Response.Write(&quot;
Context action invoked.&lt;hr/&gt;
&lt;ul&gt;&quot;);
	Response.Write($&quot;
&lt;li&gt;Current HttpContext in &lt;strong&gt;controller context&lt;/strong&gt; is { System.Web.HttpContext.Current.ToString() }&lt;/li&gt;

&quot;);

	//first we save the current SC
	 var sc = System.Threading.SynchronizationContext.Current;

	//instead of awaiting on Task.Run(WriteHttpContext()), we use a wrapper
	//the SC is therefore persisted both within the awaited and awaiter
	await Task.Run(() =&gt;
	{
		 sc.Post((state) =&gt;
		 {
			  WriteHttpContext().Invoke();
		  }, null);
	 }).ConfigureAwait(configureAwait);

Response.Write($&quot;
&lt;li&gt;Current HttpContext in &lt;strong&gt;controller context&lt;/strong&gt; is { System.Web.HttpContext.Current.ToString() }&lt;/li&gt;

&quot;);

	Response.Write($&quot;&lt;/ul&gt;

&lt;hr/&gt;Response complete.&quot;);
	return new HttpStatusCodeResult(200);
}
[/code]

If you recall when we walked through this sample in the first post, we saw the HttpContext being lost in the awaited Task context. Here's the output we get this time:

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part3-1.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part3-1.png" alt="" class="alignnone size-full wp-image-3215" width="549" height="177" /></a>

If we were to use this approach with the Index action instead and get the full verbose output, we would see the SC being of type <em>AspNetSynchronizationContext </em>and the task scheduler of type <em>ThreadPoolTaskScheduler</em>.

Why is that? Simply because the "posting" against the SC is not piloted by the task scheduler in this case, but it is manually requested. In other words, we are explicitly taking care of what the <em>AspNetSynchronizationContextTaskScheduler</em> would do for us!

<hr />

&nbsp;

I know, this whole story is kind of endless and can get seriously confusing at times. However, I hope this posts contains enough insight to let you understand the basic inner workings between the TPL and the ASP.NET HttpContext.

As already stressed out, I believe a code sample is worth more than a thousand words. Although the demo web app I used is not at all complicated and it is fairly easy to setup, I will soon update this post to include the link to my GitHub repo project, so you can just clone it and mess around with it!

&nbsp;

One final word to thank all the people who actively contirbute to this blog. I am humbled and impressed by receiving your feedback and I appreciate your efforts in highlighting possible mistakes or confused explanations! Also, thanks in advance to the ones who I am sure will be helping in the future too!

&nbsp;

Happy parallel HttpContexting! :)

&nbsp;

Catch you on the flipside!

&nbsp;

albigi / Alessandro Bigi]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET HttpContext in async/await patterns using the Task Parallel Library – Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-2</link>
      <pubDate>Sat, 02 Dec 2017 00:39:53 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3175</guid>
      <description><![CDATA[In case you don't recall the previous post, or just landed here, make sure to skim through it before...]]></description>
      <content:encoded><![CDATA[In case you don't recall the <a href="https://blogs.msdn.microsoft.com/friis/2017/12/02/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-1/">previous post</a>, or just landed here, make sure to skim through it before continue reading.

We left with some very boring theoretical discussions. As promised, we will get to the juicy bits this time!
<h2>Investigation - Part 1</h2>
Let's focus on the sample controller we built and give it a few spins:
<h3>Run 1</h3>
<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part2-0.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part2-0.png" alt="" class="alignnone size-full wp-image-3195" width="600" height="799" /></a>

Red numbers represent calls to the Log method from the MVC controller itself. Blue numbers, instead, are calls to the Log method originating within a Task.

Let's analyze the flow:
<ol>
 	<li>The controller executes on thread 79. Nothing remarkable here. All the information is available.</li>
 	<li>The controller awaits DoStuff, which is scheduled to run on the same thread. No information is lost here</li>
 	<li>We are back executing the controller. The thread is now 77 as the previous one was disengaged while awaiting the async call. No information is lost here as the SC is flown to the new thread</li>
 	<li>Here we are awaiting again, on the StartNew API this time. Note at this stage DoStuff is again executed on thread 79, but the SC is no longer available (it has not flown to the new thread). We do get information loss here as the HttpContext is also no longer available</li>
 	<li>When the execution resumes in the controller, we are back to normal.</li>
</ol>
At this stage I believe everyone should have clear one thing: if DoStuff needed to access the HttpContext (e.g. reading the session on the inbound cookies), we would have got a NullReferenceException!
<h3>Run 2</h3>
I know my readers are quick and they know exactly what happens if we run the code using ConfigureAwait(false). However, for the discussion's sake, it actually took me a while to understand the output below. Hence I decided to include it in the post!

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part2-1.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part2-1.png" alt="" class="alignnone size-full wp-image-3185" width="597" height="801" /></a>

If you are familiar with using ConfigureAwait(false), this output shouldn't surprise you. If you are not (as I wasn't myself), check again <a href="https://blogs.msdn.microsoft.com/pfxteam/2012/06/15/executioncontext-vs-synchronizationcontext/">this great post</a>. :)

In a nutshell: ConfigureAwait(true) is the default behavior when awaiting a task. This causes the SC to be captured and once the awaited task completes, the continuation is "posted" against the previously captured SC. On the contrary, ConfigureAwait(false) does not capture the SC and suppresses its flowing upon the task completion.In our example this means the awaiter (controller context) resumes discarding the current SC once the first DoStuff task completes (step 3). The controller has therefore lost its SC (as we see in the following steps).
<blockquote>Note: when a task is posted against a SC, this essentially means the Post method of the SC is invoked. The Post method queues the task to be appropriately worked. As you can see, the whole capturing of and posting against the SC is completely independent from the EC flow and the task scheduler used. The SC exposes a higher abstraction layer: it doesn't care how tasks are scheduled and worked, it is agnostic with respect to the low level implementation details.</blockquote>

<hr />

<h2>Investigation - Part 2</h2>
Let's start with a quick summary:
<ul>
 	<li>Awaiting on native TPL async APIs, such as Task.Run or TaskFactory.StartNew, causes the SC to be lost</li>
 	<li>Likewise, the SC is lost when awaiting on non-primitive async methods and ConfigureAwait(false) is used</li>
 	<li>If the SC is not flown, so doesn't the HttpContext and all the ASP.NET state</li>
</ul>
So far so good, I guess! We understood the SC is vital for the HttpContext to be persisted and if, for whatever reason, the SC doesn't flow along with the EC, we might end up getting a NullReference when trying to access the ASP.NET request state.

Well, how do we force the SC to flow along with our async code then?
<h3>Run 3</h3>
Let's take a look at what happens if we run the test page with the tsFromSyncContext switch set to true.

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part2-2.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part2-2.png" alt="" class="alignnone size-full wp-image-3186" width="639" height="806" /></a>

The issue is gone!! Black magic?! :)

&nbsp;

From a code perspective, tsFromSyncContext switched on just changes this line of code

[code lang="csharp" highlight="5"]
await Task.Factory.StartNew(
	async () =&gt; await DoStuff(doSleep, configAwait).ConfigureAwait(configAwait),
	System.Threading.CancellationToken.None,
	TaskCreationOptions.None,
	TaskScheduler.Current);
[/code]

into:

[code lang="csharp" highlight="5"]
await Task.Factory.StartNew(
async () =&gt; await DoStuff(doSleep, configAwait).ConfigureAwait(configAwait),
System.Threading.CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSyncrhonizationContext())
[/code]

&nbsp;

Any guess what's happening?! Yes!! You got it, I know you do!

The line highlighted caused the awaiter to use the AspNetSyncrhonizationContextTaskScheduler instead of the ThreadPoolTaskScheduler. The former is obviously aware of the importance of the SC and this is why it ensures the current SC flows. The latter instead, as previously mentioned, is a hard worker: its main goal is to maximize throughput and performance, therefore it tries to leave behind as much overhead as possible, including the SC.

<hr />

Before we jump into the <a href="https://blogs.msdn.microsoft.com/friis/?p=3196&amp;preview=true">next post</a> for the conclusions and you start to get seriously bored by my writing, let me leave you with a challenge!

What do you expect to happen when calling the Index action with:
<ul>
 	<li>configureAwait = false</li>
 	<li>tsFromSyncContext = true</li>
</ul>
If you followed me so far, you should be able to figure it out. Or even better, run the web app and see it for yourself!

Honestly, it took me a while to properly understand what is going on and which line of code in our web app is accountable for what behavior.

&nbsp;

The answer to the challenge in the <a href="https://blogs.msdn.microsoft.com/friis/?p=3196&amp;preview=true">next post</a>, but just a quick hint…this is a tricky question! :)

&nbsp;

albigi]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET HttpContext in async/await patterns using the Task Parallel Library - Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-1</link>
      <pubDate>Sat, 02 Dec 2017 00:24:57 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3156</guid>
      <description><![CDATA[Hopefully brief but yet needed introduction
For a long time, when ASP and ASP.NET WebForms were the...]]></description>
      <content:encoded><![CDATA[<h2>Hopefully brief but yet needed introduction</h2>
For a long time, when ASP and ASP.NET WebForms were the latest trend, web developers had to rely mainly on synchronous programming. After all, server computing can count on multithreading and it's free from UI thread freezes. While users don't normally accept a client application freezing the UI for more than a few seconds, they are more prone waiting for a webpage to load. Moreover, AJAX and all browser-driven web requests can be used to split the page loading across multiple requests, each one running synchronously on a dedicated server thread. As far as simple web pages are concerned, this approach still works fairly decently today. Asynchronous programming is not necessary to render trivial page content or push some JS code to the client browser. However, as web applications grow in complexity, background tasks are getting more and more vital. Asynchronous programming plays a key role in modern web applications, allowing them to run background operations without significant impacts for user requests being served at the same time.

The main advantages of offloading long-running operations are essentially two:
<ol>
 	<li>The server is able to serve requests quicker, possibly informing the user with regular updates on the background processing status. This remarkably increases the user experience (I guess we are all familiar with that horrible feeling when we are like "should I click back or reload the page? Will I have to fill in the form all over again?")</li>
 	<li>The server can offload the long-running operations, so that request threads are freed up and can be used to accommodate more incoming requests. This remarkably lowers the odds of starving the thread pool and eventually queue the requests or drop them with a service unavailable message.</li>
</ol>
Asynchronous programming is not new in .NET. However, starting with .NET Framework 4 the TPL (<a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl">Task Parallel Library</a>) has taken over the stage as it offers a broad and easy-to-use set of APIs to write asynchronous code. My own naïve definition for TPL is "<i>the set of libraries introducing Tasks-related types and the async/await operators</i>" (as I said, that is extremely naïve and oversimplified. Async experts, please accept my apologies!)

&nbsp;

There are lots of great discussions and blog posts about the TPL and asynchronous programming patterns in .NET. A quick search should bring up the latest and coolest ones.

Although being familiar with the topic surely eases the reading of this post, I wouldn't say that is a strict requirement. Given the complexity and broadness of the topic, I will try to focus on a very specific problem.

&nbsp;

This first post describes the initial problem and introduces all the main characters of our discussion. Two more poss will follow: the first to add more details about the investigation; the second to summarize the topic and wrap up all the findings of the previous posts.

<hr />

<h2>The problem</h2>
it is simple, in its formulation. Randomly our web application throws a NullReferenceException while performing asynchronous operations. With further investigation and debugging we realize that, while handling a request, the <b>System.Web.HttpContext.Current object is nul</b>l.

The HttpContext object stores all the request-relevant data, including the pointers to the native IIS request object, the ASP.NET pipeline instance, the Request and Response properties, the Session (and many others). Without all of this information, we can safely tell our code is unaware of the request context it is executing into. Designing entirely stateless web applications is not easy and implementing them is indeed a challenging task. Moreover, web applications are rich of third party libraries, which are generally black boxes where unspecified code runs.

How could it be that such a fundamental object, the HttpContext, is lost during the request execution? What can we do if it happens in our code and what approach should we take if it's happening inconsistently in third party libraries?

Let's focus on an practical example and consider the code below:

[code lang="csharp" highlight="8"]
public class HomeController : Controller
{
	public async Task&lt;ActionResult&gt; Context()
	{
		Response.Write(&quot;&lt;br/&gt;Context action invoked.&lt;hr/&gt;&lt;ul&gt;&quot;);
		Response.Write($&quot;&lt;li&gt;Current HttpContext in &lt;strong&gt;controller context&lt;/strong&gt; is { System.Web.HttpContext.Current.ToString() }&lt;/li&gt;&quot;);

		await Task.Run(WriteHttpContext());

		Response.Write($&quot;&lt;/ul&gt;&lt;hr/&gt;Response complete.&quot;);
		return new HttpStatusCodeResult(200);
	}
	private Action WriteHttpContext()
	{
		return delegate ()
		{
			var context = System.Web.HttpContext.Current;
			Response.Write($&quot;&lt;li&gt;Current HttpContext in &lt;strong&gt; awaited Task context&lt;/strong&gt; is &quot; +
			$&quot;{ (context == null ? &quot;null&quot; : context.ToString()) }&quot; +
			$&quot;&lt;/li&gt;&quot;);
		};
	}
}
[/code]

This is an action method on a MVC controller. In my tests I compiled it against .NET 4.7, but the behavior should be unchanged for any other supported version (currently, 4.5.2 or above).

The controller writes directly into the response output buffer and returns upon completion (no Views involved).

The core part is the code line highlighted: the controller pauses the execution while an async task is executed. In this example, the task just writes more data into the response output buffer. Although this is not really a consuming operation that would require a background task, I tried to keep the code as short and simple as possible. So bear with me and let's pretend it actually makes sense to execute WriteHttpContext asynchronously.

If you load the page you would see this output:

<a href="https://msdnshared.blob.core.windows.net/media/2017/12/part1-0.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/12/part1-0.png" alt="" class="alignnone size-full wp-image-3165" width="516" height="191" /></a>

Blimey! :)

The HttpContext was lost, for real!

<hr />

<h2>Some quick (yet due) theory</h2>
Boring. I know….but I really cannot figure out a way to explain the juicy bits without mentioning a few key concepts.

Let me introduce you some good friends from the TPL: the <b>TaskScheduler</b>, <b>the ExecutionContext </b>and the <b>SynchronizationContext</b>?

TaskWhat? ExecutionWho? :)
<ul>
 	<li>The <b>TaskScheduler</b> is exactly what you would expect. A scheduler for tasks! (I would be a great teacher!)
Depending on the type of .NET application used, a specific task scheduler might be better than others. ASP.NET uses the <b>ThreadPoolTaskScheduler</b> by default, which is optimized for throughput and parallel background processing.</li>
 	<li>The <b>ExecutionContext (EC) </b>is again somehow similar to what the name suggests. You can look at it as a substitute of the TLS (thread local storage) for multithreaded parallel execution. In extreme synthesis, it is the object used to persist all the environmental context needed for the code to run and it guarantees that a method can be interrupted and resumed on different threads without harm (both from a logical and security perspective). The key aspect to understand is the EC needs to "flow" (essentially, be copied over from a thread to another) whenever a code interrupt/resume occurs.</li>
 	<li>The <b>SynchronizationContext (SC) </b>is instead somewhat more difficult to grasp. It is related and in some ways similar to the EC, albeit enforcing a higher layer of abstraction. Indeed it can persist environmental state, but it has dedicated implementations for queueing/dequeuing work items in specific environments. Thanks to the SC, a developer can write code without bothering about how the runtime handles the async/await patterns.</li>
</ul>
There are a few very important takeaways about the SC:
<ul>
 	<li>ASP.NET has its own one, named AspNetyncrhonizationContext</li>
 	<li>The AspNetSynchronizationContext is responsible for making the HttpContext current, that is setting the static propery System.Web.HttpContext.Current to the HttpContext object related to the current request being processed.</li>
 	<li>Unlike the EC, the SC does not have to flow from thread to thread. It can, but it is not strictly necessary. Whether it actually does flow or not depends on the specific implementation of the async/await pattern.</li>
</ul>
To extensively understand how all of these elements come into play and how they seamlessly work together, I strongly recommend you to read <a href="https://blogs.msdn.microsoft.com/pfxteam/2012/06/15/executioncontext-vs-synchronizationcontext/">this great post.</a>

<hr />

<h2>Investigation - Part 0</h2>
I studied Telecommunications Engineering at university. A rather theoretical subject, I would say. Then my professional career led me to study Computer Science. One of the aspects I like most about it is the opportunity to challenge myself in problem-solving with a practical approach. In situations like this, I cannot deny some theoretical basis are of great value to understand the problem context. However, there is nothing like opening an IDE and writing down some code to test and assess what happens in real life. Luckily for us, this is a fairly quick task and all we have to do is re-decorate our sample web app:

[code lang="csharp" highlight="7,8,12-18"]
public async Task&lt;ActionResult&gt; Index(bool doSleep = false, bool configAwait = true, bool asyncContinue = true, bool tsFromSyncContext = false)
{
	Response.Write($&quot;{Log(&quot;Index called.&quot;)}&lt;br/&gt;&lt;hr/&gt;&lt;br/&gt;&quot;);
	var currentContext = System.Threading.SynchronizationContext.Current;
	try
	{
		await DoStuff(doSleep, configAwait)
			.ConfigureAwait(configAwait);

		Response.Write($&quot;{Log(&quot;await DoStuff completed.&quot;)}&lt;br/&gt;&lt;hr/&gt;&lt;br/&gt;&quot;);

		await Task.Factory.StartNew(
			async () =&gt; await DoStuff(doSleep, configAwait)
				.ConfigureAwait(configAwait),
			System.Threading.CancellationToken.None,
			asyncContinue ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None,
			tsFromSyncContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current)
			.Unwrap().ConfigureAwait(configAwait);                  

		Response.Write($&quot;{Log(&quot;await new Task completed&quot;)}&lt;br/&gt;&lt;hr/&gt;&quot;);
	}
	catch (Exception e)
	{
		Response.Write($&quot;{Log($&quot;Error {e.Message}&quot;)}&lt;br/&gt;&quot;);
	}

	return new HttpStatusCodeResult(200);
}
static string Log(string msg)
{
	var syncCtx = System.Threading.SynchronizationContext.Current;
	var taskSchdlr = TaskScheduler.Current;
	var httpCtx = System.Web.HttpContext.Current;
	return $&quot;{msg} &lt;ul&gt;&lt;li&gt;&quot; +
		$&quot;Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId} &lt;/li&gt;&lt;li&gt;&quot; +
		$&quot;Task scheduler: {taskSchdlr} &lt;/li&gt;&lt;li&gt;&quot; +
		$&quot;Sync Context: {syncCtx} &lt;/li&gt;&lt;li&gt;&quot; +
		$&quot;Http Context: {httpCtx} &lt;/li&gt;&lt;/ul&gt;&quot;;
}

async Task DoStuff(bool doSleep = true, bool configAwait = true)
{
	if (doSleep)
	{
		Response.Write($&quot;{Log($&quot;DoStuff called. configAwait is &lt;strong&gt;{configAwait.ToString()}&lt;/strong&gt;. Sleep is called&quot;)}&lt;br/&gt;&quot;);
		await Task.Run(async () =&gt; System.Threading.Thread.Sleep(SLEEPINTERVALMS)).ConfigureAwait(configAwait);
	}
	else
	{
		Response.Write($&quot;{Log($&quot;DoStuff called. configAwait is &lt;strong&gt;{configAwait.ToString()}&lt;/strong&gt;. GetAsync is called&quot;)}&lt;br/&gt;&quot;);
		await new System.Net.Http.HttpClient().GetAsync(&quot;https://www.microsoft.com&quot;).ConfigureAwait(configAwait);
	}
}

[/code]

Ok, I know, lots of re-decorations and debugging output. The juicy part is just the two lines highlighted above.

I don't think it is worth discussing on the controller implementation, but here's a quick reference to better understand the query string parameters:
<ul>
 	<li><b>configAwait: </b>controls the ConfigureAwait behavior when awaiting tasks (read on for additional considerations)</li>
 	<li><b>tsFromSyncContext: </b>controls the TaskScheduler option passed to the StartNew method. If true, the TaskScheduler is built from the current SynchronizationContext, otherwise the Current TaskScheduler is used<b>.</b></li>
 	<li><b>doSleep</b>: if True, DoStuff awaits on a Thread.Sleep. If False, it awaits on a HttpClient.GetAsync operation
Useful if you want to test it without internet connection</li>
 	<li><b>asyncContinue</b>: controls the TaskCreationOptions passed to the StartNew method. If true, the continuations are run asynchronously.
Useful if you plan to test continuation tasks too and to assess the behavior of task inlining in case of nested awaiting operations (doesn't affect LegacyASPNETSynchronizationContext)</li>
</ul>
&nbsp;

Alright, I think I can safely admit this is possibly one of the most verbose posts of mine. Time to wrap it up and call it a day as we are going to deep dive into all of the above in the <a href="https://blogs.msdn.microsoft.com/friis/2017/12/02/asp-net-httpcontext-in-asyncawait-patterns-using-the-task-parallel-library-part-2/">next post</a>!

&nbsp;

albigi]]></content:encoded>
    </item>
    <item>
      <title>Error "431 Failed to setup secure session" when connecting to a FTP Server with multiple FTP sites</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/error-431-failed-to-setup-secure-session-when-connecting-to-a-ftp-server-with-multiple-ftp-sites</link>
      <pubDate>Tue, 28 Nov 2017 16:25:30 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3015</guid>
      <description><![CDATA[Summary for lazy readers
Let's consider this scenario:

 	We are using FTPs (FTP over SSL) to...]]></description>
      <content:encoded><![CDATA[<h2>Summary for lazy readers</h2>
Let's consider this scenario:
<ul type="disc">
 	<li><span>We are using FTPs (FTP over SSL) to connect to a FTP site hosted on a Windows Server 2008 or later</span></li>
 	<li><span>We have multiple FTP sites using SSL and we are using the <a href="https://docs.microsoft.com/en-us/iis/configuration/system.ftpserver/serverruntime/hostnamesupport">virtual hostname feature</a></span></li>
 	<li><span>FTP clients suddenly report connection error: "431 Failed to setup secure session"</span></li>
 	<li><span>The FTP site certificate has been renewed or it is still valid</span></li>
</ul>
Let's also add a few conditions more:
<ul type="disc">
 	<li><span>We have another FTP site using a wildcard FTPs binding (no virtual hostname used)</span></li>
 	<li><span>The certificate used by the wildcard FTP site is expired or invalid</span></li>
</ul>
&nbsp;

As you may have guessed already, <strong>the key is to make sure a valid certificate is used by the FTP site using the wildcard binding.</strong>

<hr />

<h2>Moar details1!</h2>
When I faced this issue myself, my very first question was:
<p style="text-align: center"><em>What's the link between the two FTP sites? Aren't they supposed to be completely unrelated?</em></p>
&nbsp;

The quick answer is: yes and no :)

From a resource isolation perspective, they are completely unrelated. Each site has its own directories, ACLs, authentication enforcement and so on.

However, the link between the two does exist when it comes to the binding definition.

&nbsp;

To go through the detailed answer, we first need to understand how virtual hostnames work.

Virtual hostnames do not exist in the FTP protocol. Although <a href="https://tools.ietf.org/html/rfc7151">RFC 7151</a> defines the HOST command, which extends the FTP commands subset, not all clients and servers implement it. As far as Windows Server and FTP 7 or later are concerned, the virtual hostname feature entirely relies on the proprietary implementation defined in the article referenced earlier:
<blockquote><em>the virtual host name is used as part of the user name during the login process</em></blockquote>
Virtual hostnames are a clever way to cope with the two contrasting goals:
<ul type="disc">
 	<li><span>Have multiple FTP sites</span></li>
 	<li><span>Have all the sites bound to the same IP &amp; Port</span></li>
</ul>
Quite as much as HTTP SNI does, virtual hostnames allow clients to inform the server about the specific site they are intending to reach. This allows the server to disambiguate among multiple sites listening on the same port.

While SNI is an extension over the TLS handshake protocol, meaning the server can be informed about the client will to reach a specific hostname before the HTTP request is actually processed, in FTPs (being it implicit or explicit) there is no way to use such feature. Using virtual hostnames is a good workaround, but it causes the client "intentions" to be unveiled to the server only during the FTP handshake, which means once the TLS channel has been already brought up and the incoming request mapped to the destination site.

&nbsp;

Did you guess what's the caveat here? :)

Let me show you with a practical example.

<hr />

<ul type="disc">
 	<li><span>My FTP server be1i.albigi.lab has two sites: FTPA and FTPB</span></li>
 	<li><span>Both are using a FTPs implicit, with binding on IP 172.23.8.163 and port 990</span></li>
 	<li><span>FTPA is not using virtual hostnames and the SSL certificate bound to it is self-signed and has </span><span>localhost </span><span>as subject name (invalid according to the client)</span></li>
 	<li><span>FTPB is using virtual hostname ftpb.albigi.lab and its certificate is a valid one issued by the domain authority with</span><span> be1i.albigi.lab</span><span> as subject name</span></li>
</ul>
&nbsp;

Here's how they look like in IIS Manager:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/130.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/130.png" alt="" class="alignnone size-full wp-image-3035" width="437" height="36" /></a>

And here's the <span>netstat -ano</span> output after both sites are up and running:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/215.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/215.png" alt="" class="alignnone size-full wp-image-3045" width="609" height="83" /></a>

Notice there is one only binding on port 990 (actually two, if we consider the IPv6 binding) and the process listening on it is the FTP Service:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/313.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/313.png" alt="" class="alignnone size-full wp-image-3055" width="472" height="67" /></a>

&nbsp;

Below are the client connection settings:
<ul type="disc">
 	<li><span>FTPA</span></li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/11/412.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/412.png" alt="" class="alignnone size-full wp-image-3065" width="385" height="131" /></a>
<ul type="disc">
 	<li><span>FTPB</span></li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/11/4b.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/4b.png" alt="" class="alignnone size-full wp-image-3145" width="385" height="190" /></a>

Here's where the magic happens: the connections are exactly identical but the FTPB one uses a username prefix (yes, for anonymous users too!)

&nbsp;

Now, here's what happens from a client perspective:
<ul type="disc">
 	<li><span>FTPA</span></li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/11/511.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/511.png" alt="" class="alignnone size-full wp-image-3075" width="394" height="164" /></a>

This is totally what we would expect, right?

Depending on the client used and its configuration, receiving an invalid certificate can either show a security prompt (like the one in the screenshot) or simply do not trust the server and close the connection. <strong>This is when the error 431 Failed to setup secure session gets logged</strong>.
<ul type="disc">
 	<li><span>FTPB</span></li>
</ul>
Believe it or not (I don't like to believe, so I would encourage you to test this out for yourself) we get the same prompt!

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/66.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/66.png" alt="" class="alignnone size-full wp-image-3085" width="399" height="166" /></a>

For both sites, discarding the warning and telling the client to ignore the certificate validation issues results into a successful connection.

&nbsp;

What's going on?
<ul type="disc">
 	<li><span>FTPA</span></li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/11/77.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/77.png" alt="" class="alignnone size-full wp-image-3095" width="179" height="64" /></a>

The FTP client logs show this:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/84.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/84.png" alt="" class="alignnone size-full wp-image-3105" width="450" height="149" /></a>
<ul type="disc">
 	<li><span>FTPB</span></li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/2017/11/94.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/94.png" alt="" class="alignnone size-full wp-image-3115" width="129" height="60" /></a>

And the client logs:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/105.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/105.png" alt="" class="alignnone size-full wp-image-3125" width="444" height="148" /></a>

&nbsp;

A part from the FTP USER command, there are no differences at all!

&nbsp;

By now, I believe you should have guessed what's actually happening. But we are curious and we like to play geeky games, right?

Let's change the FTPB site SSL settings so that it is not bound to any certificate:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/1114.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/1114.png" alt="" class="alignnone size-full wp-image-3135" width="221" height="213" /></a>

Logically speaking, a FTP site with such settings should never work.

From our client, let's connect to the FTPB site…wait, what? It's still complaining about the certificate but it's working!

Surprised, are you? I don't believe so! :)

Ok, enough playing!

<hr />

<h2>Let's wrap it up!</h2>
&nbsp;
<ul type="disc">
 	<li><strong>There is one and only one actual SSL binding up!</strong></li>
</ul>
<p style="padding-left: 30px">Which one?</p>

<ul type="disc">
 	<li><span><strong>The SSL certificate set in the most general binding is used</strong>.</span></li>
</ul>
<p style="padding-left: 30px">Why?</p>

<ul type="disc">
 	<li><span><strong>A site not using virtual hostnames is considered to have a more general binding, </strong>thus FTPA configuration is honored.</span></li>
</ul>
<p style="padding-left: 30px">Do I have to setup a FTPB site then?</p>

<ul type="disc">
 	<li><span>Of course! FTPB configuration comes into play only when the FTP client has shared his will to connect to FTPB by sending the virtual hostname in the USER prefix. <strong>Once the FTP handshake is complete, the life cycle of the communication is completely separated between the two sites</strong>.</span></li>
</ul>
<p style="padding-left: 30px">Do I need to bind the SSL Certificate to all of the FTP sites?</p>

<ul type="disc">
 	<li><span>Ah! Good question! No, you do not. <strong>The SSL channel is always established between the client and the FTP site with the most general matching binding configuration</strong>.
If you have many FTPs sites with different virtual hostname bindings, a good strategy is to have a "general" site (wildcard binding) used for central administration of the SSL certificate. </span><span>The site can be as simple as possible and don't authorize any user (it doesn't really matter as during the FTP logon the proper site based on the virtual hostname is selected). All the other actual sites do not need any specific SSL configuration.
</span></li>
</ul>
&nbsp;

<strong>So, if we want to solve the error "431 Failed to setup secure session", let's first make sure the site handling the FTPs connection in the first place uses a valid certificate!</strong>

&nbsp;

&nbsp;

Catch you guys on the flip side!

&nbsp;

<em>albigi / Alessandro</em>]]></content:encoded>
    </item>
    <item>
      <title>Putting it all together – CORS tutorial</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/putting-it-all-together-cors-tutorial</link>
      <pubDate>Fri, 24 Nov 2017 19:54:13 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=3007</guid>
      <description><![CDATA[Hosting the two sites on IIS and understanding the request flow and needed configuration to allow...]]></description>
      <content:encoded><![CDATA[<span style="color: #44546a">Hosting the two sites on IIS and understanding the request flow and needed configuration to allow the entire application work correctly is what we will focus on in this article. This far, <a href="https://blogs.msdn.microsoft.com/friis/2017/11/24/setting-up-cors-request-with-windows-integrated-authentication-and-asp-net-core">in this tutorial</a> we have gone through creating the front-end website using Razor Pages and the back-end HTTP web-service using WebAPI, as well as preparing the two solutions for publishing on IIS as explained in: <a href="https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=aspnetcore2x">https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=aspnetcore2x</a> . Since the application is expected to run using Windows Integrated authentication there will be a couple of more steps that we will need to take in both solutions to make sure that the ASP.net Core interacts correctly with IIS and is forwarded the authentication tokens from the IIS worker process (w3wp.exe).
</span>

<span style="color: #44546a">The first thing to accomplish, is to setup the applications to work with IIS. This is achieved in the Startup.cs class of each of the two projects. We will be adding IIS as a service, in the ConfigureServices method, using the options pattern. The only option we are interested in is having the applications configured for Windows Authentication. This is done by setting the AutomaticAuthentication option and setting to true. The code is shown below:
</span>

<span style="color: blue;font-family: Consolas;font-size: 9pt">public <span style="color: black"><span style="color: blue">void<span style="color: black"> ConfigureServices(IServiceCollection services)
</span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt">    services.AddMvc();
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: green;background-color: silver">//needed to enable IIS integration with Windows Auth
</span></span><span style="background-color: silver;color: black;font-family: Consolas;font-size: 9pt"><span>    </span>services.Configure&lt;IISOptions&gt;(options =&gt;
</span><span style="background-color: silver;color: black;font-family: Consolas;font-size: 9pt">    {
</span><span style="background-color: silver;color: black;font-family: Consolas;font-size: 9pt">        options.AutomaticAuthentication = true</span><span style="color: blue"><span style="color: black">;
</span></span><span style="background-color: silver;color: black;font-family: Consolas;font-size: 9pt">     });</span>

<span style="color: black;font-family: Consolas;font-size: 9pt"> }
</span>

<span style="color: #44546a">The highlighted code is what needs to be added to the ConfigureServices method in both projects, after which they should be recompiled and published.
</span>

<span style="color: #44546a">Inside the IIS Manager Console, I recommend setting two websites (they can be on different servers on the same server) and setting up HTTP bindings with host header entries, for <strong>corerazor</strong> and <strong>corewebapi</strong>, by selecting the 'Bindings' action for each website:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital1.png" alt="" /><span style="color: #44546a;font-family: Courier New;font-size: 9pt">
</span>

<span style="color: #44546a">Host bindings for CoreRazor – front end website
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital2.png" alt="" />

<span style="color: #44546a">Host bindings for CoreWebAPI – backend http webservice application
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital3.png" alt="" /><span style="color: #44546a;font-family: Courier New;font-size: 9pt">
</span>

<span style="color: #44546a"><em>SIDE NOTE:</em> If you plan to host both websites on the same Windows server, and if you have no DNS so that you can setup CNAME aliases for the hostnames <strong>coreRazor</strong> and <strong>coreWebApi</strong> , you can modify the hosts file of the computer you will be accessing the website from to map the two entries to your server's IP address. To do this, you may wish to follow the article below: <a href="https://www.petri.com/easily-edit-hosts-file-windows-10">https://www.petri.com/easily-edit-hosts-file-windows-10</a> .
</span>

<span style="color: #44546a">The second step in configuring the two applications to use Windows Integrated authentication, is to configure the ASP.net Core Platforms Handler to forward the Windows integrated authentication token to the dotnet.exe process that is hosting the application. The easiest way to achieve this is using the Configuration Editor in the IIS Mangeger console. Just select each of your sites, and then double click the 'Configuration Editor' icon in the middle pane:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital4.png" alt="" /><span style="color: #44546a">
</span>

<span style="color: #44546a">Once inside this feature, you will be able to access any configuration relating to the website, that is coming either from ApplicationHost.config file or the website's web.config file. Using the dropdown control from the top of the Configuration Editor window, select the System.WebServer/AspNetCore tag from the list of availabe tags as shown:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital5.png" alt="" /><span style="color: #44546a;font-family: Courier New;font-size: 9pt">
</span>

<span style="color: #44546a">Within this section, you will find all of the possible configuration for the ASP.net Core Platforms Handler. Among the settings is one called <strong>forwardWindowsAuthToken</strong> whish should be set to 'true', in order for the module to forward the authentication token to the dotnet.exe process.
</span>

<span style="color: #44546a">Next, we need to understand the request flow, which may be then most important part of this tutorial. Nothing gets the point across better than a visual diagram:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital6.png" alt="" /><span style="color: #44546a;font-family: Courier New;font-size: 9pt">
</span>

<span style="color: #44546a">In the above diagram, the client browser will:
1. Make a request to <a href="https://coreRazor/asyncPoster">https://coreRazor/asyncPoster</a> . The request will be of type GET and will result in the Razor Page executing on the server and sending back some HTML markup to the browser to render.</span>

Once the page is displayed, the user will proceed and enter some text in the text area control and press the 'Echo Text' button. At this point the interesting stuff starts to happen.

<span style="color: #44546a">2. The JavaScript engine will send a CORS preflight request to the <a href="https://coreWebAPI/api/EchoCors">https://coreWebAPI/api/EchoCors</a> url. The purpose of this request is to make sure that the website allows requests coming from another site (notably <a href="https://coreRazor">https://coreRazor</a>) to be sent and processed. The request materializes as an OPTIONS request on the wire, and the following HTTP headers are sent out:
</span>

<span style="color: #222222"><span style="font-family: Consolas;font-size: 9pt">OPTIONS /api/EchoCors HTTP/1.1
Host: corewebapi
Connection: keep-alive
<span style="background-color: silver">Access-Control-Request-Method: POST
Origin: https://corerazor</span>
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Access-Control-Request-Headers: content-type Accept: */*
Accept-Encoding: gzip, deflate</span><span style="color: #44546a">
</span></span>

<span style="color: #44546a">I have underlined the important information in red – the Origin header indicates where the Javascript that is perfoming the CORS request originated from: https://corerazor. The Access-Control-Request-Method indicates what kind of request the script woud like to make (a POST request in this case). According to: https://fetch.spec.whatwg.org/#cors-preflight-fetch , the CORS preflight request has to go out without any authentication. And this is the main problem in our case.
</span>

<span style="color: #44546a">If you have followed along with the tutorial up to this point, you will know that Windows Integrated Authentication will reject any requests that are sent without credentials, and the response from the IIS server will be a 401 status code, requesting authentication. This will not allow the JavaScript engine to know if requests from the origin site are allowed to the target backend site, and will result in failure.
</span>

<span style="color: #44546a">In order to remedy this, we need to modify the IIS settings, for the backend <a href="https://coreWebAPI">https://coreWebAPI</a> site to allow anonymous requests in certina cases. This is where a good understanding of the HTTP pipeline in IIS comes in handly, and I would suggest a detour to video number 2 in the IIS Architecture and Components videos I have posted online a while ago: <a href="https://linqto.me/n/IISArchitecture">https://linqto.me/n/IISArchitecture</a> . The HTTP processing pipeline is based on events being raised and pieces of code called 'http modules' subscribing to the notificatins sent out on these events to perform changes to the request or the response.
</span>

<span style="color: #44546a">Two pipeline stages are important here: 1) Authentication and 2) Authorization. In the authentication stage, we are trying to understant who is the user behind the request. So we may chose to say the user is the 'anonymous user', and that annonymous authentication should also be turned on. Below are the authentication settings on IIS for the <a href="https://coreWebAPI">https://coreWebAPI</a> site – note that both Windows Integrated Authentication and Anonymous Authentication are enabled:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital7.png" alt="" /><span style="color: #44546a">
</span>

<span style="color: #44546a">In the next stage of request processing, the Authorization stage (or Authorization event), we need to make sure we only allow the anonymous requests from CORS preflight and require all other incoming requests have authentication credentials supplied. We can achieve this through Authorization Rules. A default authorization rule granting all users access to the site is already in place and supplied by default by IIS. We will start by modifying this rule to only allow anonymous users, if they send requests that are using the OPTIONS http verb. Below is the target configuration in IIS for this authorization rule:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital8.png" alt="" /><span style="color: #44546a">
</span>

<span style="color: #44546a">However, this authorization rule is not enough as it will block all other requests. We need a second 'Allow' Authorization rule that needs to be introduced. This rule will perimit access to the application to a desired group of users – for the demonstration, I have chosen the 'Users' group, which should include most authenticated user accounts from the server where the backend application is hosted. In a real world scenario, we would configure an Active Directory group, such as 'Domain Users' if a really large scope was targetted, or some more restrained, like a specific user group.
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1827_Puttingital9.png" alt="" /><span style="color: #44546a">
</span>

<span style="color: #44546a">Here is what the web.config file for the backend website will contain following the modifications to the authorization rules:
</span>

<span style="color: black;font-family: Courier New;font-size: 9pt">&lt;system.webServer&gt;
&lt;handlers&gt;
&lt;add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /&gt;
&lt;/handlers&gt;
&lt;aspNetCore processPath="dotnet" arguments=".\WebApiEcho.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" /&gt;
&lt;security&gt;
&lt;authentication&gt;
&lt;anonymousAuthentication enabled="true" /&gt;
&lt;windowsAuthentication enabled="true" /&gt;
&lt;/authentication&gt;
&lt;authorization&gt;
&lt;remove users="*" roles="" verbs="" /&gt;
&lt;add accessType="Allow" users="?" verbs="OPTIONS" /&gt;
&lt;add accessType="Allow" users="" roles="USERS" /&gt;
&lt;/authorization&gt;
&lt;/security&gt;
&lt;/system.webServer&gt;
</span>

<span style="color: #44546a">These two rules will ensure that: CORS preflight OPTION request rules will be honored without requiring authenticatin, will all other incoming requests will need to present valid credentials to be allowed through to our ASP.net Core WebAPI application.
</span>

<span style="color: #44546a">If we review the response headers for the CORS preflight request shown earlier, we can see that the server does authorize the receipt of CORS request from the <a href="https://coreRazor">https://coreRazor</a> website:
</span>

<span style="color: #222222;font-family: Consolas;font-size: 9pt">HTTP/1.1 200 OK
Vary: Origin
Server: Kestrel
<span style="background-color: silver">Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Origin: https://corerazor</span>
X-Powered-By: ASP.NET
Content-Length: 0
</span>

<span style="color: #44546a">In the highlighted headers, we can see that the server is indicating that CORS requests to this server from the website are allowed if they supply credentials, and if the requests orginates from the <a href="https://coreRazor">https://coreRazor</a> site. With this information, the JavaScript engine can now proceed to perform the POST request with JSON content to send to the WebAPI controller for processing.
</span>

<span style="color: #44546a">By <strong>Paul Cociuba</strong></span>
<a href="https://linqto.me/about/pcociuba">https://linqto.me/about/pcociuba</a>

<span style="color: #222222;font-family: Consolas;font-size: 9pt">
</span>]]></content:encoded>
    </item>
    <item>
      <title>Building the ASP.net Core WebAPI backend – CORS tutorial</title>
      <link>https://docs.microsoft.com/archive/blogs/friis/building-the-asp-net-core-webapi-backend-cors-tutorial</link>
      <pubDate>Fri, 24 Nov 2017 19:53:55 GMT</pubDate>
      <dc:creator><![CDATA[friis[at]microsoft.com]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/friis/?p=2945</guid>
      <description><![CDATA[With the front end site complete, we can shift focus to building the WebAPI backend that will be...]]></description>
      <content:encoded><![CDATA[<span style="color: #44546a">With the <a href="https://blogs.msdn.microsoft.com/friis/2017/11/24/building-the-asp-net-core-razor-pages-site-cors-tutorial">front end site complete</a>, we can shift focus to building the WebAPI backend that will be powering the Echo Text service. Just as for the front-end site, In Visual Studio 2017, you can choose to create a new Project, and select the 'Web' category. Give the project a name and then select the WebAPI application template from the second step of the new project Wizard. Do not forget to setup Windows Integrated as an authentication method for this backed application as well, by pressing the Change Authentication button in this step of the Wizard.
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1821_Buildingthe1.png" alt="" /><span style="color: #44546a">
<span style="color: #c00000"><strong>
</strong></span></span>

<span style="color: #44546a">Once the project is created on disk by Visual Studio, you can proceed and delete the ValuesController class that is located under the 'Controllers' folder inside the Solution Explorer. Then add a new Controller to the folder, and chose the WebAPI Empty Controller template:
</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1821_Buildingthe2.png" alt="" />

<span style="color: #44546a">Call the new controller 'EchoCorsController'. Be careful, for the project to work as shown here, you will need to respect the name of the controller class, otherwise the JavaScript code from the previous tutorial will not POST to the correct url.
</span>

<span style="color: #44546a">For completeness, I will also be using a model class to represent the data received from the front end site. To achieve this, create a Models folder in the solution, and add a class called TextMessage inside. The end result should have the project looking like the following in the solution explorer:</span>

<img src="https://msdnshared.blob.core.windows.net/media/2017/11/112417_1821_Buildingthe3.png" alt="" />

<span style="color: #44546a">The TextMessage class contains a single string property called EchoText, and is a POCO object (Plain old CLR objet):
</span>

<span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">public <span style="color: black"><span style="color: blue">class <span style="color: black"><span style="color: #2b91af">TextMessage
</span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">   public <span style="color: black"><span style="color: blue">string<span style="color: black"> EchoText { <span style="color: blue">get<span style="color: black">; <span style="color: blue">set<span style="color: black">; }
</span></span></span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">}</span>

<span style="color: #44546a">It will be an instance of the TextMessage object that we will be binding to in the EchoCorsController when receiving the JSON data from the front end. Here is the code of the controller class:
</span>

<span style="color: black;font-family: Consolas;font-size: 9pt"> [Produces(<span style="color: #a31515">"application/json"<span style="color: black">)]
</span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">[Route(</span><span style="font-family: Consolas;color: #a31515;font-size: 9pt">"api/EchoCors"<span style="color: black">)]
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">public <span style="color: black"><span style="color: blue">class <span style="color: black"><span style="color: #2b91af">EchoCorsController<span style="color: black"> : Controller
</span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: green">     // POST api/echocors
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt">     [HttpPost]
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">     public<span style="color: black"> IEnumerable&lt;<span style="color: blue">string<span style="color: black">&gt; Post([FromBody]TextMessage eMessage)
</span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">     {</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue"><span style="color: black">
</span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: green">           //return back a JsonResult to echo the text<span style="color: black">
</span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">           return <span style="color: black"><span style="color: blue">new <span style="color: black"><span style="color: blue">string<span style="color: black">[] { <span style="color: #a31515">"Echo back:"<span style="color: black"> + eMessage.EchoText };
</span></span></span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue"><span style="color: black"><span style="color: blue"><span style="color: black"><span style="color: blue"><span style="color: black"><span style="color: #a31515"><span style="color: black">     }
</span></span></span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">}
</span>

<span style="color: black;font-family: Consolas;font-size: 9pt">
</span>

<span style="color: #44546a">The controller has one method called Post. By convention this will respond to incoming Http POST requests. To make sure that the Post method is only invoked by POST requests, the [HttpPost] attribute has been added to decorate the action method.
</span>

<span style="color: #44546a">The method will take a parameter of type TextMessage (our model class), and, before invoking the action method, the MVC Framework will look to data-bind data from the request to populate the fields of this object instance. The [FromBody] attribute will indicate to the data binder that it should only seek to find suitable values for the TextMessage's properties inside the request body, and not in the query string, route data, etc…
</span>

<span style="color: #44546a">Below I have placed a POST request captured with the Chrome F12 browser tools from the front end. The part highlighted in gray represents the request body, and contains the JSON data that the front-end will be transmitting.
</span>

<span style="font-family: Courier New;font-size: 9pt">POST /api/EchoCors HTTP/1.1
Host: corewebapi
Connection: keep-alive
Content-Length: 48
Accept: application/json, text/javascript, */*; q=0.01
Origin: https://corerazor
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Content-Type: application/json
Referer: https://corerazor/AsyncPoster
Accept-Encoding: gzip, deflate
</span>

<span style="font-family: Courier New;font-size: 9pt"><span style="background-color: lightgrey">{"echoText":"Life is too short - learn ASP.net"}</span>
</span>

<span style="color: #44546a">The last two steps of the implementation will have us making sure that only authenticated users can access the controller's POST method, and setting up CORS access.
</span>

<span style="color: #44546a">Ensuring only authenticated users are allowed to access the POST method of the controller is very simple. The [Authorize] attribute will be used to make sure that all requests are authenticated before the action method code will be executed:
</span>

<span style="color: green;font-family: Consolas;font-size: 9pt"> // POST api/echocors
</span><span style="color: black;font-family: Consolas;font-size: 9pt">[HttpPost]
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="background-color: lightgrey">[Authorize]
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt">[EnableCors(</span><span style="font-family: Consolas;font-size: 9pt;color: #a31515">"AllowSpecificOrigin"<span style="color: black">)]
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">public<span style="color: black"> IEnumerable&lt;<span style="color: blue">string<span style="color: black">&gt; Post([FromBody]TextMessage eMessage)
</span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: green">    //return back a JsonResult to echo the text<span style="color: black">
</span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">    return <span style="color: black"><span style="color: blue">new <span style="color: black"><span style="color: blue">string<span style="color: black">[] { <span style="color: #a31515">"Echo back:"<span style="color: black"> + eMessage.EchoText };
</span></span></span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">}</span>

<span style="color: #44546a">By default, and for security purposes, Javascript on a page can only formulate and send requests back to the server the page was loaded from. Since the front end site page was loaded from <a href="https://corerazor">https://corerazor</a></span>
<span style="color: #44546a">it should not be able to send requests to another server called <a href="https://corewebapi">https://corewebapi</a></span> . <span style="color: #44546a">To allow this to happen, we need to setup CORS – Cross Origin Requests. This is explained in the following tutorial:</span>
<a href="https://docs.microsoft.com/en-us/aspnet/core/security/cors">https://docs.microsoft.com/en-us/aspnet/core/security/cors</a> .

<span style="color: #44546a">I will outline the steps, and also explain some of the extras we need to do in our project. The first thing is to install the ASP.net Cors Nuget package. A simple command in the Nuget Package manager console for our solution will help us achieve this:
</span>

<span style="font-family: Courier New;font-size: 9pt">Install-Package Microsoft.AspNetCore.Cors
</span>

<span style="color: #44546a">This command will bring in the Nuget package and make sure that all dependencies are in place to start working with CORS.
</span>

<span style="color: #44546a">Once the package is installed, it has to be enabled. There are OWIN services are to be configured in the project's startup.cs class in the ConfigureService method. Let's start with the services configuration:
</span>

<span style="color: blue;font-family: Consolas;font-size: 9pt">public <span style="color: black"><span style="color: blue">void<span style="color: black"> ConfigureServices(IServiceCollection services)
</span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt">     services.AddCors(options =&gt;
</span><span style="color: black;font-family: Consolas;font-size: 9pt">     {
</span><span style="color: black;font-family: Consolas;font-size: 9pt">          options.AddPolicy(</span><span style="font-family: Consolas;font-size: 9pt;color: #a31515">"AllowSpecificOrigin"<span style="color: black">, </span></span><span style="color: black;font-family: Consolas;font-size: 9pt">builder =&gt;
</span><span style="color: black;font-family: Consolas;font-size: 9pt">          {
</span><span style="color: black;font-family: Consolas;font-size: 9pt">                 builder.WithOrigins(</span><span style="font-family: Consolas;font-size: 9pt;color: #a31515">"https://dev-web17:81"<span style="color: black">, </span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: #a31515"><span style="color: black"><span style="color: #a31515">"https://corerazor"<span style="color: black">);
</span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">                 builder.AllowCredentials();
</span><span style="color: black;font-family: Consolas;font-size: 9pt">                 builder.AllowAnyHeader();
</span><span style="color: black;font-family: Consolas;font-size: 9pt">                 builder.AllowAnyMethod();
</span><span style="color: black;font-family: Consolas;font-size: 9pt">          });
</span><span style="color: black;font-family: Consolas;font-size: 9pt">     });</span>

<span style="color: black;font-family: Consolas;font-size: 9pt">     services.AddMvc();
</span><span style="color: black;font-family: Consolas;font-size: 9pt">}</span>

<span style="color: #44546a">Using the AddCors extension method, and the options pattern, we will add the Cors service before the MVC service. There are several important options we want to pass to this method. The first indicates that we will be creating a policy object called 'AllowSpecificOrigin'. Inside the policy object, we use the options pattern again to setup the parameters for this policy. We indicate the urls that we want to accept requests from – here I am adding a local url (<a href="https://dev-web17:81">https://dev-web17:81</a>) and the production url (<a href="https://corerazor">https://corerazor</a></span>
<span style="color: #44546a">). We then need to specify that we are allowing CORS requests to send credentials using the AllowCredentials extension method. We also want to specify that we accept all http headers using the AllowAnyHeader extension method. And finally, we indicate that we allow all kinds of HTTP vers (GET, POST, etc) by using the AllowAnyMethod extension method.
</span>

<span style="color: #44546a">Once the CORS access policy is declared in the Startup.cs class of the project, we can augment the controller action method with an attribute which will apply the policy we have defined at the previous step. The action method code is augmented with the EnableCors attribute, which takes as an argument, the name of the policy we created when setting up the CORS service:
</span>

<span style="color: green;font-family: Consolas;font-size: 9pt"> // POST api/echocors
</span><span style="color: black;font-family: Consolas;font-size: 9pt">[HttpPost]
</span><span style="color: black;font-family: Consolas;font-size: 9pt">[Authorize]
</span><span style="color: black;font-family: Consolas;font-size: 9pt">[EnableCors(</span><span style="color: #a31515;font-family: Consolas;font-size: 9pt">"AllowSpecificOrigin"<span style="color: black">)]
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">public<span style="color: black"> IEnumerable&lt;<span style="color: blue">string<span style="color: black">&gt; Post([FromBody]TextMessage eMessage)
</span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">{
</span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: green">     //return back a JsonResult to echo the text
</span></span><span style="color: black;font-family: Consolas;font-size: 9pt"><span style="color: blue">     return <span style="color: black"><span style="color: blue">new <span style="color: black"><span style="color: blue">string<span style="color: black">[] { <span style="color: #a31515">"Echo back:"<span style="color: black"> + eMessage.EchoText };
</span></span></span></span></span></span></span></span></span><span style="color: black;font-family: Consolas;font-size: 9pt">}</span>

<span style="color: #44546a">With this last modification, the project is complete and we can proceed with IIS publishing just like the front-end project. You can refer back to the front-end tutorial for publishing ASP.net Core projects to IIS: <a href="https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=aspnetcore2x">https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=aspnetcore2x</a></span> .

<span style="color: #44546a">Proceed to the next article in the <a href="https://blogs.msdn.microsoft.com/friis/2017/11/24/putting-it-all-together-cors-tutorial">series -&gt;</a>
</span>

<span style="color: #44546a">By <strong>Paul Cociuba</strong></span>
<a href="https://linqto.me/about/pcociuba">https://linqto.me/about/pcociuba</a>]]></content:encoded>
    </item>
  </channel>
</rss>