User-specific IIS config - visual-studio

Under MyProject > Properties > Web there is an option to "Apply server settings to all users" which stores the IIS config in MyProject.csproj.user.
However, there doesn't seem to be a way to set defaults. Meaning anyone who clones the project will have to customize these settings.
Is there a way to set defaults when using user-specific IIS settings?
I've attempted to use environment variables, but Visual Studio complains that it cannot create an IIS binding for http://$(API_HOST):$(API_PORT)/

What is the setting you need to set? This is an important detail.
Most of the configuration could be setted in the web.config file infact this file has a "system.webServer" section dedicated to IIS Configuration.
example:
<system.webServer>
<defaultDocument enabled="true">
<files>
<add value="Default.htm" />
<add value="Index.htm" />
<add value="Index.html" />
</files>
</defaultDocument>
<directoryBrowse enabled="true" />
<httpErrors>
<error statusCode="404" prefixLanguageFilePath="%SystemDrive%\inetpub\custerr" path="my_custom_404.htm" />
</httpErrors>
<security>
<authentication>
<anonymousAuthentication enabled="true" userName="IUSR" />
<basicAuthentication />
<clientCertificateMappingAuthentication />
<digestAuthentication />
<iisClientCertificateMappingAuthentication />
<windowsAuthentication />
</authentication>
<requestFiltering>
<fileExtensions allowUnlisted="true" applyToWebDAV="true" />
<verbs allowUnlisted="true" applyToWebDAV="true" />
<hiddenSegments applyToWebDAV="true">
<add segment="Web.config" />
</hiddenSegments>
</requestFiltering>
</security>
<staticContent lockAttributes="isDocFooterFileName">
<mimeMap fileExtension=".mp3" mimeType="otect/stream" />
</staticContent>
</system.webServer>
source:
https://learn.microsoft.com/en-us/iis/configuration/system.webserver/

Related

Flask Web App with Windows Authentication

I have Flask app on IIS similiar to this tutorial : https://medium.com/#nerdijoe/how-to-deploy-flask-on-iis-with-windows-authentication-733839d657b7 but I'm using httpPlatformHandler instead of FastCGI.
With web.config as below I get None in REMOTE_USER :
request.environ.get('REMOTE_USER')
web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpPlatform stdoutLogEnabled="true" stdoutLogFile=".\python.log" startupTimeLimit="20" processPath="C:\python3\python.exe" arguments="-m flask run --port %HTTP_PLATFORM_PORT%">
</httpPlatform>
<httpErrors errorMode="DetailedLocalOnly" />
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</configuration>
How to get username of a user logged to a site using Flask on IIS?

Why does the name of my Publish Profile affect the transformation of my Web.config?

I think I have encountered a strange interaction where the name of my Publish Profile is affecting the contents of the published Web.config.
For context, I have 2 solution configurations; Release & Staging, and a folder Publish Profile called 'Release.pubxml'. Below are stripped down versions of the three web configs involved.
Web.config:
<configuration>
<connectionStrings>
<add name="DBEntities" connectionString="{Web.config connection string}" />
</connectionStrings>
<appSettings>
<add key="WEBSITEURL" value="http://website.com" />
<add key="ADMINURL" value="http://admin.website.com" />
</appSettings>
</configuration>
Web.Release.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Release.config connection string}" />
</connectionStrings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPtoHTTPSredirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Web.Staging.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Staging.config connection string}" />
</connectionStrings>
<appSettings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="WEBSITEURL" value="http://stagingwebsite.com" />
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="ADMINURL" value="http://admin.stagingwebsite.com />
</appSettings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
</configuration>
I had recently adjusted our Staging web config, and tried publishing under the Release.pubxml profile, but with the Configuration set to Staging, rather than Release. The result I expected was the original Web.config file, with all Web.Staging.config xdt transformations applied.
What ended up happening was a Frankenstein mix of the Web.Staging.config and the Web.Release.config transforming into Web.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="DBEntities" connectionString="{Web.Release.config connection string}" />
</connectionStrings>
<appSettings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="WEBSITEURL" value="http://stagingwebsite.com" />
<add xdt:Transform="SetAttributes" xdt:Locator="Match(key)" key="ADMINURL" value="http://admin.stagingwebsite.com />
</appSettings>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPtoHTTPSredirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
You'll notice it has the Release connection string, the Staging WEBSITEURL/ADMINURL, and the Release HTTP rules.
I could not find any trace of the Release configuration anywhere in my settings. I had checked the configuration manager and all projects were set to build as Staging & I had cleaned/rebuilt multiple times. I had also tested it with both VS 2022 & VS 2019, and with multiple, separate solutions; each yielded the same result.
What ended up "fixing" it, was changing the name from 'Release.pubxml' to anything but Release.pubxml or Staging.pubxml. Although you wouldn't usually want to name your publish profile anything outside of what its configured to, why does the name of the publish profile override the configuration build you have set? With some further investigation, it seems that it might be transforming the chosen configured build first (Staging), then it transforms any config with the same name as your publish profile (Release).
This interaction seems extremely dangerous to me, so would anybody be able to explain to me why Visual Studio would do this (or if I have maybe encountered a bug)?

Configure URL Rewrite using server variable to support multiple origins

I was dealing with CORS issue a couple days ago where I need to support multiple origins. I did some research and found a couple posts pointing me to this great tool (URL Rewrite). I got the solution I wanted following Paco Zarate tip here: Access-control-allow-origin with multiple domains using URL Rewrite. I also found another post here: http://www.carlosag.net/articles/enable-cors-access-control-allow-origin.cshtml showing me how to achieve the same solution with a different method of configuration within URL Rewrite.
Paco Zarate solution works like a charm. Why am I still asking question? It's just for learning purposes. And also I think the second post configuration yields a more elegant list of origins/domains I want to white-listed. For ease of maintainability I can just go to the Rewrite Maps and see all of my AllowedOrigins.
When attempted the second post's solution, I got this message: ERR_CONNECTION_RESET under Console tab of the browser debugger tool. And the request header under Network tab says "Provisional headers are shown"
Many thanks in advance.
My config file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed" />
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Headers" value="Origin, Content-Type, Accept" />
<add name="Access-Control-Request-Method" value="POST" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Origin" value="http://localhost:8080" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<rule name="Capture Origin Header">
<match url=".*" />
<conditions>
<add input="{HTTP_ORIGIN}" pattern=".+" />
</conditions>
<serverVariables>
<set name="CAPTURED_ORIGIN" value="{C:0}" />
</serverVariables>
<action type="None" />
</rule>
<rule name="Preflight Options" enabled="false" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^OPTIONS$" />
</conditions>
<action type="CustomResponse" statusCode="200" statusReason="Preflight" statusDescription="Preflight" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="AllowedOrigins">
<add key="http://somedomain:8080" value="http://localhost:8080" />
</rewriteMap>
</rewriteMaps>
<outboundRules>
<rule name="Set-Access-Control-Allow-Origin for known origins">
<match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern=".+" negate="true" />
<conditions>
<add input="{AllowedOrigins:{CAPTURED_ORIGIN}}" pattern=".+" />
</conditions>
<action type="Rewrite" value="{C:0}" />
</rule>
</outboundRules>
</rewrite>
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="WWW Server" areas="Rewrite" verbosity="Verbose" />
</traceAreas>
<failureDefinitions timeTaken="00:00:00" statusCodes="500" verbosity="Error" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
I had a lot of issues trying to use URL Rewrite module to enable CORS, after a lot of troubleshooting I found that for IIS 7.5+ you can use IIS CORS Module: https://www.iis.net/downloads/microsoft/iis-cors-module
Your web.config should be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="http://localhost:8080" allowCredentials="true">
<allowMethods>
<add method="POST" />
</allowMethods>
</add>
</cors>
</system.webServer>
</configuration>
You can find the configuration reference in here: https://learn.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference

web.config transform: not the debug.cofig values when debugging locally

I am trying to change the values of some appsetting keys while running locally.
So, i have my original Web.config which has thoses keys
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="config" value="Release" />
</appSettings>
I am trying to change the value of "config" key in the web.debug.config,
<?xml version="1.0"?>
<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="config" value="Debug" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>
<system.web>
</system.web>
</configuration>
When, i am running the project locally using VS:
I am printing the value of config and is always showing the value from web.config, however when i click preview transformation on web.debug.config, its showing this:
how can i make it work locally by picking information from web.debug.config?

How to Specify Last-Modified or ETag header to enable Cache Validation on IIS 8.5

I want to specify a cache validator for google font on IIS 8.5.
http://fonts.googleapis.com/css?family=Open+Sans:400,400italic,300,700,600
What I did on my web.config is below;
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="10.00:00:00" />
</staticContent>
I also added caching by extension
<caching>
<profiles>
<add extension=".woff" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="23:59:00" />
<add extension=".ttf" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="23:59:00" />
<add extension=".gif" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="23:59:00" />
<add extension=".js" policy="CacheForTimePeriod" kernelCachePolicy="CacheUntilChange" duration="23:59:00" />
<add extension=".png" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="23:59:00" />
<add extension=".jpg" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="23:59:00" />
<add extension=".css" policy="CacheForTimePeriod" kernelCachePolicy="CacheUntilChange" duration="23:59:00" />
</profiles>
</caching>
But I am still not able to apply cache-validator for Google Font that I used. I am also tried to set an expire time to E.g. May 2030 for static content but Google PageSpeed didnt recognized that also. * I have managed to do it with .httaccess, and checked .htaccess topics on stackoverflow. *
You can apply a cache validor only for contents that your server sevrs not external content ;-).
Moreover it's a false positive because Google fonts have cache control directives:
https://redbot.org/?uri=http%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DOpen%2BSans%3A400%2C800

Resources