IIS Rewrite root folder to different subfolders - asp.net

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.

Related

redirect url from web.config file not working properly

I want to remove my html extension but failed when going with in the directory.
link1 of my site working properply but other directory links are not working properly.
link2
i want to remove html extension at the end this link
http://mremind.com/products-services/credentialing.html
but after my rewrite
http://mremind.com/products-services/credentialing/
which is not working.
In stackover flow other question i found the solution of my problem but its not working properly.
my solution in web.config file is
<rewrite>
<rules>
<rule name="Hide .html ext">
<match ignoreCase="true" url="^(.*)"/>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
<add input="{REQUEST_FILENAME}.html" matchType="IsFile"/>
</conditions>
<action type="Rewrite" url="{R:0}.html"/>
</rule>
<rule name="Redirecting .html ext" stopProcessing="true">
<match url="^(.*).html"/>
<conditions logicalGrouping="MatchAny">
<add input="{URL}" pattern="(.*).html"/>
</conditions>
<action type="Redirect" url="{R:1}"/>
</rule>
</rules>
</rewrite>
I think what you want needs another rewrite rule. You redirect from credentialing.html to credentialing, but that file does not exist so you are probably getting a 404.
What you need is a rule that adds the .html extension again as a rewrite so IIS can find the file again.
<rule name="No html ext" stopProcessing="true">
<match url="^([a-z0-9-_/]+)$" ignoreCase="true" />
<action type="Rewrite" url="{R:1}.html" />
</rule>

IIS Url rewrite rule for Angular SPA + WebApi

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=".*|.*/.*$" />

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.

IIS 7 Wordpress URL Redirect

So I have a site.com/blog/12/12/articleNames and i want to redirect everything to site.com/articles/12/12/articleNames instead.
so in my blog folder i have this in my web.config
<rewrite>
<rules>
<rule name="articleMove" stopProcessing="true">
<match url="^blog/([0-9]+)/([0-9]+)/([_0-9a-z-])/" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
</conditions>
<action type="Rewrite" url="/articles/{R:1}/{R:2}/{R:3}" />
</rule>
</rules>
</rewrite>
However, i still keep getting the 404 page.
Use IIS Failed Request Tracing to further investigate what is happening "behind the scenes".
<rule name="articleMove" stopProcessing="true">
<match url="^([0-9]+)/([0-9]+)/([_0-9a-z-]+)" />
<action type="Redirect" url="/articles/{R:1}/{R:2}/{R:3}" />
<conditions>
</conditions>
</rule>
So if the URL is http://site.com/blog/whatevergoeshere. Ignore the blog part. and each split you just do {R:1} etc.. so if the url was http://site.com/blog/12/10/the-article-name and you want it to be http://site.com/articles/12/10/the-article-name is what the above does.

Rewrite rule to map locations to static files

What I want to do it rewrite urls for a bunch of static pages in a locations folder such that
/london
maps to the physical file if it exist in the locations folder eg.
/locations/london.aspx
Is this possible with url rewrite. I can't get the rule to work.
<rule name="Rewrite Locations">
<match url="^([_0-9a-z-]+)/*" />
<conditions>
<add input="/locations/{REQUEST_FILENAME}.aspx" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="/locations/{R:1}.aspx" />
</rule>
Many thanks,
Ian
For the IsFile to work you have to pass the right physical path and not the virtual path, you can do something like:
<rule name="Locations" stopProcessing="true">
<match url="^([_0-9a-z-]+)/*" />
<conditions>
<add input="{APPL_PHYSICAL_PATH}locations\{R:1}.aspx" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="/locations/{R:1}.aspx" />
</rule>

Resources