IIS Url rewrite rule for Angular SPA + WebApi - iis-7

I have a SPA + WebAPI application, they are both in the same project. I only want the WebAPI application to process requests from the directory "api". So anything under api will be handled by the server, everything else will be handled by the Angular SPA.
I currently have
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
This works OK except when I go to the URL
http://localhost/customers/2 (which loads the doc but all resources are coming in with the wrong mime type I have concluded its because of the redirect rules above)
the URL http://localhost/customers works fine will be routed by my SPA app
How do I get everything to be redirected to my SPA except for the requests that come under the API directory?

I do this with two rules. One to "whitelist" the server-side controllers I want to go to asp.net, which includes /api but also the authentication stuff under /Account and /Manage. The next sends everything else to angular unless it's a file or folder, much like what you already have.
<rule name="API Rule" stopProcessing="true">
<match url="^(api|account|manage)(.*)$" />
<action type="None" />
</rule>
<rule name="Angular Rule" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
Try it this way, but feel free to remove "|account|manage" if you don't want those requests going to the server.
To see my entire ruleset, check out this question I have posted, where I handle HTTPS and canonical hostnames as well.

Update this line
<match url=".*" />
To this
<match url=".*|.*/.*$" />

Related

IIS not secured after adding hid aspx ext to URL rewite

I have a windows server 2016 Standard.
I have SSL installed and working fine. I also add the following to URL rewrite to redirect http to https:
<rules>
<rule name="ssl redirect" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" />
</rule>
</rules>
Now I added a Rule to hide my extension:
<rule name="hide .aspx ext" enabled="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}.aspx" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:0}.aspx" />
</rule>
However, now, I don't get the secure symbol (the lock icon) any more and saying the site is not secure. what am I doing wrong?
Thanks for any help
URL rewrite shouldn't report this error when you just rewrite for friendly URL.Did you receive this error in Edge or chrome?
1.I notice that you are using MatchAny for your rule.Based on my understanding you should use MatchAll instead.
<rule name="hide .aspx ext" enabled="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}.aspx" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:0}.aspx" />
</rule>
2.What error message did you receive when chrome report site is not secure? Did you
receive something likeNET::ERR_CERT_COMMON_NAME_INVALID ? Please open chrome F12 developer tool->Seucrity. You should be find the root cause. Please ensure your are using a valid certificate with valid domain and SAN.
3.Please ensure the http binding and https binding are hosted in differernt site. To
enable SSL, you need to enable Require SSL. Then SSL handshake will corrupt http request from same site. So you need another site to handle http request and do the redirection.

How to redirect Wordpress blog through IIS in combination with existing ASP.NET site

I started installing (through the Web Installer Platform) a Wordpress blog on my Windows (2012) Server.
On this server I'm already hosting a ASP.NET MVC 4.5 site.
Now, before I can proceed configuring the Wordpress site (by opening www.***.com/wp-config.php),
I seem to create a new redirect rule in IIS / web.config.
Otherwise it will give conflicts with the existing ASP.NET site.
I have tried this redirect rule:
<rule name="wordpress blog" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
<add input="{REQUEST_URI}" pattern="^/(blog)" negate="true"/>
</conditions>
<action type="Rewrite" url="index.php"/>
</rule>
With this rule, when opening https://www.****.com/blog/wp-config.php I end up with a runtime error on https://www.****.com/blog/error?aspxerrorpath=/blog/wp-config.php
And when adding in www.***.com/wp-config.php (so in the root folder)
<rule name="block" stopProcessing="true">
<match url="^blog$" />
<action type="none" />
</rule>
and going to https://www.***.com/blog/wp-config.php, I am getting the same errorpage as above.
I can't seem to figure out how this rule should look like. Is there anyone who can help me out there?
According to your description, I suggest you could try to use belwo url rewrite rule in the asp.net application.
This rule will redirect all the request with blob to the index.php.
<rule name="wordpress blog" >
<match url="blog/(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="http://{yourdomian}/blog/index.php"/>
</rule>
It was solved by adding "blog" in the global.asax.cs in the ExclusionFilter as follows:
i18n.UrlLocalizer.QuickUrlExclusionFilter = new System.Text.RegularExpressions.Regex(#"(?:sitemap.xml|.css|.jpg|.png|.svg|.woff|.woff2|.eot|.js|.html|.json)$|(?:blog)");

Changing the URL Extension

I had developed a Web application in Asp.net. When am using the Application over IIS, the file extension as.aspx is visible. Is it possible to hide it (or) rename it....Thankx in advance.
For .NET framework 4.0+, try the following rule in web.config (inside <system.webServer>):
The first will redirect URLs using the old format, to remove the .aspx extensions. You should of course update your links as well - eventually you won't need this.
The second rule rewrites URLs internally to add .aspx behind the scenes.
<rewrite>
<rules>
<rule name="RedirectOldFormat" enabled="true" stopProcessing="true">
<match url="(.*)\.aspx" />
<action type="Redirect" url="{R:1}" />
</rule>
<rule name="InternallyAddAspx" enabled="true">
<match url=".*" negate="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{URL}" pattern="(.*)\.(.*)" negate="true" />
</conditions>
<action type="Rewrite" url="{R:0}.aspx" />
</rule>
</rules>
</rewrite>
For .NET Framework 3.5 or earlier, you can accomplish this using routing. Try the following solution:
http://www.codedigest.com/Articles/ASPNET/294_Search_Engine_Friendly_URLs_Using_Routing_in_ASPNet_35.aspx

IIS Rewrite root folder to different subfolders

I'm setting up a folder structure inside an application that looks like such:
c:\inetpub\wwwroot\contoso\public
c:\inetpub\wwwroot\contoso\secured
I am wanting to map the following URLs to those folder structures:
http://www.contoso.com/login -> \public\login.aspx
http://www.contoso.com/myaccount -> \secured\myaccount.aspx
http://www.contoso.com/(css|images|js)/* -> \public(css|images|js)* (not represented in below rules)
I have the Application Request Routing Version 2 installed on the server. My thought process was that I could build a few rewrite rules to do the mapping for me such as these ...
<rewrite>
<rules>
<rule name="Rewrite pub page to aspx" stopProcessing="false">
<match url="^([a-z0-9/]+)$" ignoreCase="true" />
<conditions>
<add input="public\{REQUEST_FILENAME}.aspx" matchType="IsFile" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="public/{R:1}.aspx" />
</rule>
<rule name="Rewrite sec page to aspx" stopProcessing="false">
<match url="^([a-z0-9/]+)$" ignoreCase="true" />
<conditions>
<add input="secured\{REQUEST_FILENAME}.aspx" matchType="IsFile" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="secured/{R:1}.aspx" />
</rule>
<rule name="Rewrite 404 page to aspx" stopProcessing="true">
<match url="^([a-z0-9/]+)$" ignoreCase="true" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="public/default.aspx" />
</rule>
</rules>
</rewrite>
<location path="secured"><system.web><authorization><deny users="?"/></authorization></system.web></location>
<location path="public"><system.web><authorization><allow users="?,*"/></authorization></system.web></location>
In my mind, I was telling the condition to check if the file exists in the public folder and if so it would rewrite that file. Otherwise it'd fall through and see if the file exists in the secured folder and if so it would rewrite that file. Otherwise it would get caught by the "catch everything else" rule and just point it back to a default page.
But this is not working to my expectations ... I can get it to always rewrite to a folder but I can't get the conditions to fire to check for a file existing.
Any suggestions?
I turned tracing on within IIS and by looking through those logs I was able to discover that {REQUEST_FILENAME} was the wrong variable to use in this situation. Here's the relevant log information:
Input secured\{REQUEST_FILENAME}.aspx
ExpandedInput secured\c:\inetpub\wwwroot\contoso\myaccount.aspx
MatchType 1
Pattern
Negate false
Succeeded false
MatchType IsFile
So I went looking through the server variables list documentation and was able to find the APPL_PHYSICAL_PATH variable and changed the inputs to this:
<rule name="Rewrite sec page to aspx" stopProcessing="false">
<match url="^([a-z0-9/]+)$" ignoreCase="true" />
<conditions>
<add input="{APPL_PHYSICAL_PATH}secured\{R:1}.aspx" matchType="IsFile" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="secured/{R:1}.aspx" />
</rule>
And voila, that started matching. Hope this helps someone else in the future.

How to create custom rules in IIS Rewrite module for my sites

I am facing a problem trying to write 2 rules for redirect applications paths on IIS 8.0, using a Web.Config file inside root path.
1) I need to Redirect these URL's "www.misite.com" and "missite.com" to "~/main" folder.
2) I need to Redirect the URL "subdomain.misite.com" to "~/subdomain" folder.
For the 1st one i am using:
<rule name="Redirect to Main" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www.misite.com(/.*)?$" />
<add input="{REQUEST_URI}" negate="true" pattern="/main" />
</conditions>
<action type="Redirect" url="http://www.misite.com/main/{R:1}" />
</rule>
<rule name="Redirect to Main" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^misite.com(/.*)?$" />
<add input="{REQUEST_URI}" negate="true" pattern="/main" />
</conditions>
<action type="Redirect" url="http://www.misite.com/main/{R:1}" />
</rule>
For the 2nd one:
<rule name="Redirect to Subdomain" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^subdomain.misite.com(/.*)?$" />
<add input="{REQUEST_URI}" negate="true" pattern="/subdomain" />
</conditions>
<action type="Redirect" url="http://www.misite.com/subdomain/{R:1}" />
</rule>
The First rule works fine, but for the 2nd when i try to surf into "subdomain.misite.com" i am redirected to "http://www.misite.com/main/subdomain".
I will appreciate your help.
I think you're confusing Redirecting and Rewriting here - the behaviour you describe is exactly what I would expect given the rules cited. Initially the request is being redirected to www.misite.com/subdomain and then by virtue of your first rule that request is being redirected again to www.misite.com/main/subdomain. I think what you want to be doing here is rewrite the requests to serve the correct content for each sub-domain.
Redirection effectively means "if a request for URL 'A' arrives, forward the browser on to URL 'B'". Rewriting the request effectively means "if a request for URL 'A' is received then serve resource 'B' as if it were at URL 'A'".
I'm assuming you have the following structure-
-wwwroot
--main
--subdomain
Presumably what you want happen is that when a user goes to www.domain.com/default.aspx, the default.aspx document in the "main" directory is served, and likewise when the user visits subdomain.domain.com the default.aspx document in the "subdomain" directory is returned.
I'm also assuming you don't want the folders themselves to be part of the path, i.e. not subdomain.domain.com/subdomain/default.aspx
<rule name="Rewrite to Main directory" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www.misite.com(/.*)?$" />
<add input="{PATH_INFO}" negate="true" pattern="/main/" />
</conditions>
<action type="Rewrite" url="/main/{R:1}" />
</rule>
<rule name="Redirect to WWW" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^misite.com(/.*)?$" />
</conditions>
<action type="Redirect" url="http://www.misite.com/{R:0}" redirectType="Permanent" />
</rule>
I've left the second part of your first code block as a redirect as it is generally considered bad practice to have identical content available at multiple URLs for SEO (see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=66359) and will cause you problems with analytics. In this case I have chosen to redirect domain.com/default.aspx to www.domain.com/default.aspx, but it would be equally valid to choose to do it the other way around - you just need to make a choice and apply that consistently within your site.
I have dropped the /main/ part of the redirection path/URL as the content in the /main/ directory is what should be served by the request anyway, leaving that in the path would effectively be looking for /main/main/default.aspx. I have also added a negate on the path info condition on the first (rewrite) rule, meaning that if a request that did arrive for www.domain.com/main/default.aspx it would not be rewritten to serve content from the sub-directory - /main/default.aspx would be served instead of the (presumably non-existent) file at /main/main/default.aspx.
Lastly the sub-domain is also changed to a rewrite.
<rule name="Rewrite for Subdomain" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^subdomain.misite.com(/.*)?$" />
<add input="{PATH_INFO}" negate="true" pattern="/subdomain/" />
</conditions>
<action type="Rewrite" url="/subdomain/{R:1}" />
</rule>
See http://weblogs.asp.net/owscott/archive/2010/01/26/iis-url-rewrite-hosting-multiple-domains-under-one-site.aspx for more info on this topic.

Resources