Accessing pre-configured IIS response headers from a web service - asp.net

How to access IIS-configured response headers from a Web API 2 service?
In my IIS configuration there is a pre-configured response header Environment=DEV, which I need to check to figure out which environment settings to use.
When I check headers in my current response via HttpContext.Current.Response.Headers, I'm only seeing Server, and nothing else.

I don't think you should dependent on response headers as they are added to response by IIS at a very later stage in the pipeline and the control is already out of WEB API.
If you have to do this you can go with URL Rewrite + Server Variables. Install URL Rewrite and add a rule in your web.config under system.webServer as below
<rewrite>
<rules>
<rule name="GetEnvironmentInfo">
<match url=".*" />
<serverVariables>
<set name="Environment" value="Dev" />
</serverVariables>
<action type="Rewrite" url="{R:0}" />
</rule>
</rules>
</rewrite>
Also you can add this rule from IIS UI. Now depending upon webAPI configuration you can fetch server variables using below code
string output = string.Empty;
if (Request.Properties.ContainsKey("MS_HttpContext"))
{
output = ((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.ServerVariables["Environment"];
}
else if (Request.Properties.ContainsKey("MS_OwinContext"))
{
var httpContextWrapper = ((OwinContext)Request.Properties["MS_OwinContext"]).Environment["System.Web.HttpContextBase"] as HttpContextWrapper;
output = httpContextWrapper.Request.ServerVariables["Environment"];
}
The above XML can be generated from IIS GUI at server level
1.Install URL Rewrite.
2.Open IIS Manger (Windows Run -> Inetmgr)
3.Select Server in left menu
4.In the central pane double click URL Rewrite. In the Actions pane on the right hand side click Add Rule
5.Set values as below
and the save.
This will add same XML but now at the server level i.e. in C:\Windows\System32\inetsrv\Config\applicationHost.config file
<globalRules>
<rule name="GetEnInfo">
<match url=".*" />
<action type="Rewrite" url="{R:0}" />
<serverVariables>
<set name="Environment" value="dev" />
</serverVariables>
</rule>
</globalRules>
Regarding fetching response headers from IIS there could be a way but I wouldn't recommend it due to the reason mentioned in the beginning of the answer.
Hope this helps.

Related

ASP.NET rewrite redirect url on IIS (for Facebook social login)

I have an application that is behind a reverse proxy and when the user is trying to log in with a Facebook account, it fails because the redirect uri is an internal uri, instead of the public domain.
To come around this I want to rewrite redirected url.
This is the flow:
User logs in to Facebook
Microsoft.AspNetCore.Authentication.Facebook nuget package takes over the authentication process
A redirection (302) GET request happens to this url:
https://www.facebook.com/v2.6/dialog/oauth?client_id={clientid}&scope=public_profile,email&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fsignin-facebook&state={longstring}
And this is the part that I want to rewrite:
redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fsignin-facebook to
redirect_uri=https://mypublicdomain.com/signin-facebook
Is this possible with IIS Url rewrite module?
I tried to configure it but couldn't get it to work.
(on the server I'm using ASP.NETCORE 1.1.2)
<outboundRules>
<remove name="Rewrite Location Header" />
<rule name="Rewrite Location Header" preCondition="IsRedirection" enabled="true">
<match serverVariable="RESPONSE_Location" pattern="^https:\/\/(.*&redirect_uri=)([^&]*)(.*)" />
<action type="Rewrite" value="{R:1}https://google.com{R:3}" replace="false" />
</rule>
<preConditions>
<preCondition name="IsRedirection">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
Yes this is possible. Make sure to use the {QUERY_STRING} input to match against and ensure you have Rewrite as the action type.
A similar solution you could use as a starting point can be found here

This site can’t provide a secure connection

When I added the URL rewrite code in web.config and then publish it into azure. it will automatically redirects to https even I am trying to access website with http.
<rewrite>
<rules>
<rule name="Redirect to https">
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="Off"/>
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/>
</rule>
</rules>
</rewrite>
But when I run the same code in my local machine it gives the below error.
This site can’t provide a secure connection
How can I resolve the above error when I run the above code in my local machine?
What I do personally is put that rewrite configuration into Web.Release.config precisely because it is a bit fiddly to get it working locally.
The problem is that IIS Express will expose HTTP and HTTPS on different ports, so if you redirect from http://localhost:1234 to https://localhost:1234, it simply won't work, because IIS Express is exposing HTTPS on something like https://localhost:44300.
You can enable SSL/TLS on IIS Express (and you should), but I would leave the rewrite rule only for Release mode.
Here is an example Web.Release.config file:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<!-- Redirects users to HTTPS if they try to access with HTTP -->
<rule
name="Force HTTPS"
stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="^OFF$" ignoreCase="true"/>
</conditions>
<action
type="Redirect"
url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent"/>
</rule>
</rules>
<outboundRules>
<!-- Enforces HTTPS for browsers with HSTS -->
<!-- As per official spec only sent when users access with HTTPS -->
<rule
xdt:Transform="Insert"
name="Add Strict-Transport-Security when HTTPS"
enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Note that I also add HSTS here. It inserts the <rewrite> element into Web.config in Release mode. The <system.webServer> element already exists in Web.config, otherwise I would be inserting that.
This always solves the issue for me.
In Solution Explorer, click your project.
Hit the F4 key (view properties).
Copy the URL (NOT the SSL URL).
Paste the URL into the Project Url on the Web Tab, Save.
In Solution Explorer, click your project.
Hit the F4 key (view properties).
Change SSL Enabled to false.
Change it back to true. There should be a new SSL URL. Copy it.
Paste the new SSL URL into Project URL on Web tab. Click Create Virtual Directory.
Click Override application root URL, and paste in SSL URL. Save.
You will have to configure Visual Studio Server to be used with HTTPS.
Please go through this link for details:
HTTPS with Visual Studio's built-in ASP.NET Development Server
I solved this problem with older version of Chrome web browser.
This is the list of older chrome versions where you can download and install it.
60.0.3112.90 - for Ubuntu is the version that works just fine for me.
Maybe it's little slower then newer versions but i found it's pretty good for production (:
On my end, I found out that there was a javascript code that redirects the site from http to https. So try to explore your environment if there are other code responsible for that issue. Hope this can help. Thanks
I just changed the URL in the Web tab of the project properties to use a PORT that starts with 443, e.g. 44301. Also be sure to change http to https. It works for me.

DNS rewrite in asp.net or DNS redirection in asp.net

I have an aspx page with some HTML tags
Example
Actual url
<img src="https://google.com/fp/clear.png?latitude=<latitude>&longitude=<longitude> alt="">
How do i change the domain name (google.com) to a local URL (localgoog.com), and configure web server to redirect the URL (localgoo.com) to actual url (google.com)
Since you're referring to an aspx page, I'm assuming you're running on IIS. In that case, you may install the URLRewrite module into your IIS server. http://www.iis.net/downloads/microsoft/url-rewrite
Then, within IIS management console, you may setup a rewrite rule to redirect any url coming in with the hostname of "localgoo.com" to "google.com". Once you save this rule, your web.config file will be modified to include the XML version of your rewrite rule, which then makes your app portable to other servers as well.
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectToGoogle" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^localgoo.com$" />
</conditions>
<action type="Redirect" url="//google.com/{R:0}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
The {R:0} is a captured group of anything that comes after the hostname and appends it back onto the new hostname.

HTTP Error 500.52 - URL Rewrite Module Error.

I am trying to setup a reverse proxy with IIS 7.5. I want an incoming request that matches a certain URL pattern to be served by Tomcat. I have used the tutorial here to configure it.
http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing
My settings are as below:
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url=".*/(Locations|FacetedSearch|LocationPage)/.*" />
<action type="Rewrite" url="http://search.xxx.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" replace="true" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://search.xxx.com/(.*)" />
<action type="Rewrite" value="http{R:1}://dev.xxx.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<tracing>
HTTP Error 500.52 - URL Rewrite Module Error.
Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("deflate").
I just hit this issue as well, and I found this solution helpful: https://www.saotn.org/iis-outbound-rules-with-gzip-compression/
Basically, on inbound requests the HTTP_ACCEPT_ENCODING header gets stashed into a temporary header, and then gets restored back on the outbound rewrite rule.
In the case the link goes dead, here's the steps:
Through the IIS Manager GUI on the server node in the left pane, navigate to URL Rewrite
Click View Server Variables in the right pane
Add two Allowed Server Variables:
HTTP_ACCEPT_ENCODING
HTTP_X_ORIGINAL_ACCEPT_ENCODING
Back in URL Rewrite options for the Server, click on View Preconditions in the right pane. Add a new precondition (I named it NeedsRestoringAcceptEncoding)
Set the Condition Input to {HTTP_X_ORIGINAL_ACCEPT_ENCODING} and the Pattern to ".+" (no quotes).
On the inbound rewrite rule that is causing the error, add the following to Server Variables (you'll find it underneath the Conditions section):
Server Variable Name: HTTP_X_ORIGINAL_ACCEPT_ENCODING
Value: {HTTP_ACCEPT_ENCODING}
Server Variable Name: HTTP_ACCEPT_ENCODING
Value: ""
On the outbound rewrite rule, add the precondition created from steps 4-5 to the Precondition section of the rule (it should be populated in the drop-down box)
In the case that you only need this functionality on a single site, you can add the precondition at the site-level instead of the server-level.
Add this to your web config
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
or disable dynamic compression in iis
find "compress" in IIS,then remove the dynamic content compression and static content compression.
Disabling dynamic and static content compression from the site responsible for reverse proxying the requests AND the site that is being proxied fixed this error for me.
To put it in other words - if server X is routing requests to server Y, then disable dynamic and static content compression on the sites on both server X and Y.

IIS rewrite rule for basic auth on the querystring

I am trying to automatically log in users to an Xwiki install via basic auth. This is because help is stored in the wiki, but we want the retrieval process to be transparent to the user.
We push the user off to a url (via an <a> tag) like:
http://username:password#xwiki.example.org/xwiki/bin/view/Main?basicauth=1
This works fine in every browser except Internet Explorer (see: http://support.microsoft.com/kb/834489. Unfortunately, 80% of our user base uses Internet Explorer and it is not an option to have them type in the credentials manually.
Currently, we have IIS 7.5 sitting in front of Xwiki and proxying all requests to the Tomcat instance on another server. This works fine. To solve my problem, I thought I could use a IIS rewrite rule to turn a url like this:
http://xwiki.example.org/xwiki/bin/view/Main?basicauth=1&_username=username&_password=password
into this:
http://username:password#xwiki.example.org/xwiki/bin/view/Main?basicauth=1&_username=username&_password=password
The idea being that IIS would substitute the _username/_password querystring parameters into the URL and pass it off to Tomcat, and Xwiki would ignore the extra parameters.
I have created a URL rewrite rule like:
<rule name="BasicAuthRewrite" enabled="true">
<match url="https?://(.+)&?_username=(.+)&_password=(.+)" />
<action type="Rewrite" url="http://{R:2}:{R:3}#xwiki.example.org/{R:1}" />
</rule>
When I go 'Test pattern' in IIS and supply my url, all the backreferences ({R:x}) match up to the data I want. However, when I visit the URL in my browser, the rewrite rule fails to invoke.
Is there any way I can achieve my desired behaviour?
It is possible to do Basic authentication with URL rewrite on IIS. You should add the server variable HTTP_Authorization the value Basic followed by the username:password in base64. Remember to add the variable in the allowed variables
So for the user Aladdin with the password open sesame you the format would be Aladdin:open sesame and base64 encoded QWxhZGRpbjpvcGVuIHNlc2FtZQ==.
Which translates into
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
<rule name="SomeName" stopProcessing="true">
<match url="url/to/match" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://www.redirecturl.com/" appendQueryString="true" />
<serverVariables>
<set name="HTTP_Authorization" value="Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" />
</serverVariables>
</rule>
This should do:
<rule name="BasicAuthRewrite" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="basicauth=1&_username=(.+)&_password=(.+)" />
</conditions>
<action type="Rewrite" url="http://{C:1}:{C:2}#xwiki.example.org/{R:1}" appendQueryString="false" />
</rule>
Authorization cannot be delegated to ARR. Therefore, if the contents are highly sensitive in nature and require authorization, it is recommended that you do not enable cache.
ARR
But there is work around solution.
Solution
It appears this is not possible in IIS.

Resources