URL ReWrite Friendly-URL not working for novice programmer - url-rewriting

We're using URL ReWrite 64bit version from Microsoft on Windows 2012 R2, ColdFusion 11 Enterprise, IIS 8.5, and SQL 2008.
Forgive me for being redundant and obvious. Writing in detail is the only way I know how to get my point over. I hope it's not too much.
I've searched the site but cannot find an answer that hints at what I'm doing wrong.
So, this is my first question:
URL ReWrite is installed and seems to operate okay with some rules, but I cannot get it to do what I want with the Friendly-URL rewrite. That is the problem. I'm hoping someone will use the same basic parameters I used to see if they get the same problem on Windows or Windows Server.
Our public Announcements section on our website was written to use the ID (PK) from an SQL database table to point the URL of the an
announcement (from a list inside an sql table), with lots of categories such as jobs, events, garage-sale, etc, etc. I know, you all know
this is pretty standard for amateurs. So, as you well know, this URL method is not only clumsy, can be a security risk, but does not
easily allow for me to format the URL as I want.
The selection of announcements starts at the 'select' page:
www.domain.com/event/select.cfm
So, currently when clicking on one of the links on the select.cfm page (the list generated from a cfquery output)
I get this URL and am taken to the view page to display the actual individual announcement:
http://www.domain.com/event/view.cfm?id=23
select.cfm and view.cfm are both in the same directory inside /event/.
The anchor for the link: href="/event/view.cfm?id=#ViewInfo.ID#" (without the brackets of course).
Everything displays and works fine except for the URL I don't want.
Obviously, the folder /event/ is just off the web root, (the announcements directory) which is the only place this rule should operate.
That 'ID' I've been using in the sql table is announcement number 23 in the JOBS category. All categories and announcements are in just
the one table.
For a more friendly URL, I'd prefer to use the 'category' of each announcement and the current 'date' the announcement was saved, which
seems a pretty normal, right?
Except I'm nearly brand new at programming and really hesitated coming here.
Anyway, before attempting to use URL ReWrite, I first tried to do this:
www.domain.com/event/jobs/23/2015-12-2/view.cfm or some variation. Nothing worked the way I wanted.
It was a mess.
I quickly learned the forward slash required an actual directory on the hard drive between each slash and I could find no way around it. I
added another notch to my html synapse. I didn't want to create tons of folders and sub-folders for no good reason. So, I thought by using
the URL ReWrite I could do something like this:
www.domain.com/event/jobs-2015-12-2_3.html or some crazy variation. A couple days later my brain was hurting far too much.
I had figured this way I'd rid myself of the id= and .cfm file, and add a category which makes more sense and is easier for reference. I
may actually use part of a uniqueidentifier instead of the PK ID but that's not important for this problem.
So I stumbled onto URL REWRITE and installed it.
I opened IIS 8.5 Manager, went to the website I was using, and to the /event/ folder and clicked on URL REWRITE. I then selected Add Rule
and User-Friendly URL. I then entered the URL to one of the announcements:
"/event/view.cfm?id=" at the top of the tab, as the "internal URL".
I also tried hard coding the full URL just for a test: "/event/view.cfm?id="23" They did not work.
For each test, I entered the second example suggestion on the second line: /id/184/ just to see if it would work.
But it did not. I checked the 'web.config' file (which I will include here) in the /event/ directory and the code rules had been written
correctly. But there was there was no change to the URL as I expected when I click on the link to view.cfm. It still showed this:
www.domain.com/event/view.cfm?id=23
I tried every combination in URL ReWite I could think of but I cannot get the link to the URL to change at all, to anything, no matter
what I do. I don't get it.
I know that my installed URL ReWrite is working because of another rule I use to forward all discovered .htm files to the .cfm equivalent
when they are found.
I even did a "repair" to the installed URL ReWrite and rebooted but that did not help. Then I uninstalled URL ReWrite and installed again,
rebooted. Still no change. It works, but not with the Friendly-URL rewrite. I'm obviously doing something wrong but am at at a total loss
and might need to hire a real programmers. And that could be the end of my new job.
So, hope someone can steer me in the right direction. If so, I promise to learn and help others as I can.
Here's my web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^event/view\.cfm$" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^([^=&]+)= ([^=&]+)$" />
</conditions>
<action type="Redirect" url="event/view/{C:1}/{C:2}" appendQueryString="false" />
</rule>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^event/view/([^/]+)/([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="event/view.cfm?{R:1}={R:2}" />
</rule>
</rules>
<outboundRules>
<rule name="OutboundRewriteUserFriendlyURL1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^(.*/)event/view\.cfm\?id=([^=&]+)$" />
<action type="Rewrite" value="{R:1}event/view/id/{R:2}/" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

Related

Redirect Rule For IIS Sharepoint Site

We have our Sharepoint 2019 site set up, and everything is running fine. However, when a user clicks the Brand Bar "Sharepoint" in the top left header, it brings them to a broken page. Researched this, and it seems like this link cannot be changed in 2019, as others are having this issue.
https://social.technet.microsoft.com/Forums/en-US/1ef910ec-fb70-443e-bcf4-2d277dc11d2a/sharepoint-2019-on-premise-management-shell-not-working-as-expected?forum=SP2019
What we wanted to do is a redirect, so whenever they went to the broken link, it would just direct them to the real homepage for our sharepoint.
Example -
Broken link is http://servername/my/_layouts/15/sharepoint.aspx
Correct link is https://sharepoint.companyname.com/SitePages/Home.aspx
Here is what I came up with to add to the web.config file, but doesnt seem to be working.
<configuration>
<system.webServer>
<httpRedirect enabled="true" exactDestination="true" httpResponseStatus="Found">
<add wildcard="*_layouts/15/sharepoint.aspx" destination="https://sharepoint.companyname.com/SitePages/Home.aspx" />
</httpRedirect>
</system.webServer>
</configuration>
Any idea on what needs to be done here? Is this even possible? I didn't set up the sharepoint site here so I'm not sure how http://servername/my/_layouts/15/sharepoint.aspx even became the brand bar link.
Thank you!
If you want to redirect from servername/my/_layouts/15/sharepoint.aspx to sharepoint.companyname.com/SitePages/Home.aspx by iis url rewrite, you can try this rule.
<rule name="test6" stopProcessing="true">
<match url="^my/_layouts/15/sharepoint$" />
<action type="Redirect" url="http://sharepoint.companyname.com/SitePages/Home.aspx" />
</rule>
This has been resolved.
Not sure what happened, only thing I did was place the rule on the top most part of the tree in IIS where the server name is. Before I was putting the rule on the actual site in the drop down. I guess this makes sense since the URL I wanted to redirect had the server name in it.

IIS7: Content-Length Mismatch Due to URL Rewrite and OutboundRules Usage

I'm having some issues getting the outbound rules configured to work on IIS7, here's the scenario that's giving me grief. My ultimate goal is to get any outboundRules working within a couple of browsers. For this example, I'm using the rule that strips .aspx from various HTML tags.
Scenario 1 (Content-Length Mismatch):
To get that particular rule to work in IIS7, I had to disable dynamic compression and turn caching off by default. I was successful in getting the HTML rewritten, but another issue cropped up that makes this unusable.
When trying the rewrite content with outboundrules, I'm getting an issue where by Chrome and Firefox are performing a continuous load because of a "content-length mismatch" in the headers (Thanks Fiddler for helping me identify it). The rewrite works, but it causes the content length to be incorrect and so those two browsers look like they're loading forever. Chrome in particular this causes an issue because javascript appears to be hung up and so anything jquery doesn't work until someone physically hits the stop button.
This is the pertinent sections of the web.config that I began with in order to give me that scenario:
<system.webServer>
<rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
<modules runAllManagedModulesForAllRequests="true" />
<outboundRules>
<rule name="Remove .aspx from links in the response" preCondition="IsHTML" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, IFrame, Link, Img, Script" pattern="(.*)\.aspx(\?.*)?$" />
<action type="Rewrite" value="{R:1}{R:2}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
While researching this issue, I found this stackedoverflow question which mentioned the rewriteBeforeCache="true" attribute on the outboundRules tag as well as this blog post which laid out the same thing that I was running into with the content-length issues.
If I modify that attribute, that leads me to Outbound Rules failing to work any further.
Scenario 2 (Outbound Rules do not work):
So because of the prior information, I began tweaking the web.config and was able to resolve the content-length mismatch by using the rewriteBeforeCache attribute on the outboundRules tag. To get that attribute to work, I was able to turn caching back on. That fixed the reponse-length mismatch from Scenario 1, but now none of the outboundRules\rule elements appear to work. I have tried a number of the simplest rules and they function just fine when I remove the rewriteBeforeCache attribute, but that causes Scenario 1:
<system.webServer>
<rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
<modules runAllManagedModulesForAllRequests="true" />
<outboundRules rewriteBeforeCache="true">
<rule name="Remove .aspx from links in the response" preCondition="IsHTML" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, IFrame, Link, Img, Script" pattern="(.*)\.aspx(\?.*)?$" />
<action type="Rewrite" value="{R:1}{R:2}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
Scenario 1 causes one error with browsers in IIS7; Scenario 2 causes outboundrules to stop working.
I have modified any number of options with disabling caching, chunk-mode transfers, and trying every combination I can think to try.
Additional notes on AppPool: IIS7, .NET4.0, Classic pipeline
Does anyone else have any ideas as to what other options I have to address this beyond moving to an IIS7.5 server?

Localize error 500 page in mvc3

I've been going through stack overflow but cannot find an answer to this. I can get the 500 page to show up ok like this:
<customErrors mode="On">
<error statusCode="500"
redirect="~/500.html"/>
</customErrors>
What I would like to do is to present a localized version of the page based on the app language. Problem is that I would not like to go through the Error Controller-View solution that I found in lots of other posts, in case there is an actual error in the App (missing DLLs etc.). So I have to serve a pure html page, but I need to be able to choose the localized one, or instruct IIS on how to find it.
Any idea?
This is just off the top of my head, couldn't you use URL rewrite/redirect rules that use the Accept-Language that the browser defines to redirect to ~/500.en-us.html and ~/500.de.html or however you may have the pathing setup?
Example Rule in web.config:
<rule name="HTTP-Language-Error-Redirect" stopProcessing="true">
<match url="^500.html$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_ACCEPT_LANGUAGE}" pattern="^([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?$" />
</conditions>
<action type="Redirect" url="500.{C:1}.html" redirectType="Found" />
</rule>
My thinking is that the redwrite/redirect rule would work as it's part of IIS's processes handling the request and not the app code. So it could still work, theoretically, if the WebApp is broken for some reason. I could be totally wrong in my assumption though, and I thought I'd give it an honest shot.

Using URL Rewrite 2.0 in IIS7 and cleaning POSTs

I'm having some issues with setting up rules in URL Rewrite 2.0 using IIS 7. I'm working on a website that is a combination of more modern .NET 4.0 stuff all the way back to classic .ASP stuff. My current task is to try and strip some specific characters out of user input to help prevent against XSS attacks.
I get the basic syntax:
<rule name="Rule Name" stopProcessing="true">
<match url="myPage.asp" />
<conditions>
<add input="" pattern="" />
</conditions>
<action type="" />
</rule>
I know I need three steps,
1) Ensure that what we're looking at is a post
2) Identify any of a number of bad characters using regex
3) Continue the post with those characters stripped out.
The first I believe can be addressed by this:
<add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" />
What is frustrating me is the second and third issue.
The second is also an input, but I'm stuck trying to find the best {} variable to put in the input. Right now I have this:
<add input="{REQUEST_URI}" pattern="[\\\|<>]" />
but I know that {REQUEST_URI} is not the right variable to go there. I've been on the URL rewrite site (http://www.iis.net/download/urlrewrite), and I've found the IIS 6.0 list of server variables (http://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx), but I can't seem to find a good list of the variables available to me in 7.0 and above and what they mean. Is this something anyone has bookmarked somewhere and can pass along?
The third is also giving me issues. Right now, on some other rules, I have <action type="AbortRequest" /> set, but for this, I'm not looking to stop the request, I'm looking to just remove the bad characters and continue the POST. The custom rule setup in IIS looks promising, but it just seems to want to redirect to a URL, not do anything else. Is this something that's even possible?
I should also note that I'm looking into an IIS Managed Module as an alternative to get what I'm looking for. Does that sound like a better avenue to anyone?
So, turns out that you can't do it and that I was misinterpreting the scope of the URL rewrite application. I should be looking at an IIS Managed Module, and will pivot to that in the future.

Proxy - ASP.NET with or without MVC

I'm working on one multi-tenancy application, where each tenant will have access to 1 or more "sub applications" (different ASP.NET MVC websites).
http://v1.app1.domain.com
http://v1.app2.domain.com
http://v1.app3.domain.com
Later in time, I'll have new versions for each sub application and I will end with:
http://v1.app1.domain.com
http://v2.app1.domain.com
http://v3.app1.domain.com
http://v1.app2.domain.com
http://v2.app2.domain.com
http://v1.app3.domain.com
Some tenants will want to have access to the latest versions, and some will still be using old ones.
This is what I've done.
Now I would like to keep "the subdomain versions" hidden for them. They will only access the domain: app1.domain.com
This "internal smart proxy" will have the core to know which version this tenant has access.
Anyone knows how I can do this? In a way that all my internal urls (links, images, JS, css, etc...), AJAX,etc, will work correcly?
Or point me to some tutorials/blog/forums where i can find that can help me?
Thank you very much.
What you are trying to build is in essence an HTTP proxy. The difference to most other proxies is just that the actual URL is built on the server side.
There many different ways to do this. I'd choose one of the following:
Create an HTTP handler, in which case you could use this code project article as a starting point.
Use ASP.NET MVC. Create a "catch all" route and pipe that through one single action method.
Either way, you will have to
Analyze the HttpContext.Current.Request object and build a suitable outgoing URL
Use a HttpWebRequest to fetch the data from the actual website. Remember to mimic the original request header plus request content (usually POST parameters) if applicable.
Output the Response Header from the server and then output the data you just fetched.
Application Request Routing (ARR) could be a workable solution if you are using IIS 7 or 7.5.
You would have an additional web site defined in IIS acting as the proxy, which would be separate to the web site(s) your application uses.
The rules about which tenant is on which version would have to be written to a web.config for ARR to read. Is this acceptable? If you have a small number of tenants changing infrequently, you may be happy to edit this file by hand. If you need more automation, you could programatically generate this web.config file. Because this web.config is only for your ARR proxy site, editing it will not cause your application sites to restart.
A sample configuration might use the following IIS Sites:
proxy - binding for your public IP address. *.domain.com resolves to this address
v1app - binding for 127.0.0.101
v2app - binding for 127.0.0.102
IIS server-level settings: ARR cache -> Server Proxy Settings -> enable proxy. (Set the timeout here if your app needs long timeouts.)
And in your "proxy" site's web.config, the following rewrite rules:
<rewrite>
<rules>
<rule name="V1 tenants" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.101/{R:1}" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="app1.domain.com" />
<add input="{HTTP_HOST}" pattern="app3.domain.com" />
</conditions>
</rule>
<rule name="V2 tenants" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.102/{R:1}" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="app2.domain.com" />
</conditions>
</rule>
</rules>
</rewrite>
When a request comes in, it will hit your proxy site, then those rules will look at the hostname and redirect to the appropriate internal site.
If your ARR site is running on the same server as your content sites, you may want to remove the line
<add name="ApplicationRequestRouting" />
from C:\windows\system32\inetsrv\config\applicationHost.config, and add it as a module in your proxy site's web.config. This will apply ARR only to your proxy site, instead of the whole server.

Resources