Stop Sharing Cookies between Applications under same Site ID in IIS - iis

The issue I have is we currently are using IdentityServer as our SSO authentication for our corporate applications. However, the bulk of our applications are under the same Site ID in IIS 7.5. When navigating to more than 5 of these applications under the same Site ID, you end up getting a 400 error, request header too long. The reason being each application has its own cookie, so the request header is passing around 5+ cookies with token information and the becoming too large.
My question is, are you able to prevent the sharing of cookies between applications under the same Site ID in IIS 7.5?

We also have IdentityServer for SSO and internal applications hosted on the same machine on IIS.
And I faced with the same problem too.
Here is a solution:
1) You need to solve Owin/Katana middleware problem to avoid nonce overfloating. Here you can find the code for that fix
2) You have to stop sharing cookies.
So if your base address for applications is "mysite.com".
And you have a lot of different applications like this:
Good App: mysite.com/good_app/
Best App: mysite.com/best_app/
Super App: mysite.com/super_app/
Use CookiePath for each application on an application's side and it will limit cookies (and look here too).
Use the code like this (for "Good App"):
var cookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieName = "GoodAppCookies",
// Cookie Path same as application name on IIS
CookiePath = "/good_app
};
Hope it'll help.

Few things that you can try. Make the following changes at the server level.
Highlight the server name in IIS, select "configuration editor", select "system.web" and "httpRuntime" and change "maxRequestLength" to "1048576".
You can also edit the "applicationHost.config" file in the following way- C:\Windows\System32\inetsrv\Config
<configuration>
<system.web>
<httpRuntime maxRequestLength="1048576" />
</system.web>
</configuration>
Edit "Request Filtering" settings at server level on IIS and set "maxAllowedContentLength" to "1073741824"
You can also edit the root web.config file in the following manner - C:\Windows\Microsoft.NET\Framework64*\v4.0.30319*\Config
*Folder is based on your application. if its a 32 bit application, navigate to "Framework" folder. If its a .net 2.0 application, navigate to v2.0.50727.
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>

First of all - I want to say that I have not tried this myself, so I can't assure that it is a solution, but I'm trying to help.
The problem with the cookies originates from the Microsoft OWIN/Katana and the way they are encrypting them. They become enormous, but this has nothing to do with Identity Server. However here and here there are good discussion around this.
The main thing to try first is in the Startup.cs of the IdentityServer project, in the IdentityServerOptions.AuthenticationOptions there is a property SignInMessageThreshold which defaults to 5. Try setting it to something lower, this will keep your header smaller (which may cause round trips to identity server when an app doesn't have its message in the cookies, but this will not force the user to re-login).
Another thing, that we achieved in one of out projects, is to create a DataBase backed cookie session handler. In your clients, where you use
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieName = cookieName,
});
There is also a property SessionStore. You can have a custom implementation of the Microsoft.Owin.Security.Cookies.IAuthenticationSessionStore. In our case this reduced the cookie size to less than (or around) 300.

Related

MaxFieldLength and MaxRequestBytes setting for a 400 Bad Request

we have an IIS website that is returning 400 Bad Request for a very few users. we are using Windows Authentication
After research, I found the below info in the HTTP.err log on the server
2020-06-05 06:44:05 10.213.144.138 53021 10.11.210.147 80 HTTP/1.1 GET / - 400 - RequestLength -
I set the MaxFieldLength & MaxRequestBytes to their max values as suggested here
https://learn.microsoft.com/en-us/exchange/troubleshoot/http-proxy/400-bad-request
Still the user is receiving 400 Bad request error.
The user is part of around 200 AD groups and do not want to remove any of them.
Clear your cookies and try again, and see if you can reduce the size and amount of cookies your app is using.
When you set the registry key value you make sure you consider the below points:
1) Calculate the size of the user's Kerberos token by using the formula that's described in the following Knowledge Base article:
327825 Problems with Kerberos authentication when a user belongs to many groups
2) Set the value of MaxFieldLength and MaxRequestBytes on the server to 4/3 * T, where T is the user's token size in bytes. HTTP encodes the Kerberos token by using base64 encoding.
https://support.microsoft.com/en-us/help/2020943/http-400-bad-request-request-header-too-long-response-to-http-request
Note: Make sure you restarted the machine after doing changes.
you could also try to add below code in your site web.config file:
<configuration>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="500000000" />
</requestFiltering>
</security>
<system.webServer>
<system.web>
<httpRuntime maxRequestLength="500000000" executionTimeout="120" />
</system.web>
</configuration>
if you still face same issue try to use the fiddler or any other tool to capture network traffic and properly analyze the request and response header.

Windows Authentication MVC - 1 IIS_Express server, 2 Apps, 2 Results

Good day all
I'm completely stumped. I am developing an MVC App using MS VSExpress 2013 for Web, and am at the point where I need to add Windows Authentication. Creating a default MVC App using the Wizard and selecting Windows Authentication, it appears to work fine. Lets call the default App App1, my developed App App2.
Monitoring the Context.User object within Watch for both Apps:
App1 returns:
User {System.Security.Principal.WindowsPrincipal}
System.Security.Principal.WindowsIdentity
AuthenticationType "Negotiate" string
IsAuthenticated true bool
Name "MyDomain\\Andrew" string
When using the developed app, the result is as follows: Please note, the returned object is different (App1 = System.Security.Principle.WindowsPrinciple, App2 = System.Web.Security.RolePrinciple.
User {System.Web.Security.RolePrincipal}
Identity {System.Security.Principal.GenericIdentity}
AuthenticationType "" string
IsAuthenticated false bool
Name "" string
HttpContext.Current.Request.LogonUserIdentity.Name "MyDomain\\Andrew"
When switching the developed app Development Server properties to Windows Authentication = Enabled, Anonymous Authentication = Disabled, the result is an immediate:
Server Error in "/" Application.
Resource cannot be found.
Http 404...
Requested URL:/Account/Login
I've checked and compared:
Web.config files and IISExpress\config\applicationhost.config settings for both applications.
My limited knowledge (based on reading all the questions on SO I could find), I'm guessing App2 thinks it is using Forms Authentication, not Windows Authentication. App2 is getting the user information through the
HttpContext.Current.Request.LogonUserIdentity.Name object (found this on SO).
I've added:
<add key="autoFormsAuthentication" value="false" />
to Web.config ... no joy.
Anyone have any idea why the two apps are returning different user objects, and where this can be corrected? Why does App2 not get IsAuthenticated=true from the same IISExpress server as App1?
Thanks
http://www.itorian.com/2013/05/windows-authentication-in-mvc4-with-iis.html
For some strange reason (EDIT Here is the reason-> ASP.NET MVC3 and Windows Auth on IIS keeps redirecting to /Account/Login /EDIT , the wizard generated app1 did not require these two lines within Web.config
<add key="autoFormsAuthentication" value="false" />
<add key="enableSimpleMembership" value="false"/>
After adding the 2nd line, the Context User object returned changed from
System.Security.Principal.GenericIdentity
to
System.Security.Principal.WindowsPrincipal
and all is well.
Also ensure your IISExpress server config file applicationhost.config (within the IISExpress installation folder) contains correct entries as required:
Global Entry:
<windowsAuthentication enabled="true">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>

MVC bundle with Azure CDN - how to enable caching

I have a web site to be hosted in Azure that has a lot of javascript and CSS but very small pages. I would like to have the javascript and the CSS delivered via a CDN.
Azure provides a really neat and convenient mechanism to allow this as described here https://azure.microsoft.com/en-us/documentation/articles/cdn-cloud-service-with-cdn/#integrate-aspnet-bundling-and-minification-with-azure-cdn
In short, you add the following code to your BundleConfig.cs
bundles.UseCdn = true;
var version = System.Reflection.Assembly.GetAssembly(typeof(Controllers.HomeController))
.GetName().Version.ToString();
var cdnUrl = "http://axxxxxx6.vo.msecnd.net/{0}?v=" + version;
ScriptBundle scriptBundle = new ScriptBundle("~/bundles/xx", string.Format(cdnUrl, "bundles/xx"));
scriptBundle.Include(
"~/Scripts/modernizr-*",
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery.signalR-{version}.js",
"~/Scripts/jquery.watermark.js", ....
I have followed the instructions to the letter and on the surface it appears to work exactly as expected.
But I realised that the caching for these CDN provided resources is disabled. Every time the web page is requested the JS and the CSS are downloaded again - which defeats the purpose of the CDN altogether.
I have also included the following in the web.config
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="15.00:00:00"/>
</staticContent>
What am I missing here?
Thanks in advance.
Dave A

Why is the `Arr-Disable-Session-Affinity` header coming through on my Azure Web App (WebSite)?

Following the procedure in this article I disabled the ARR Affinity cookie on my Azure Web App with this header in my responses:
Arr-Disable-Session-Affinity: True
It does remove the cookie, which is very much a good thing. But, the header itself is still coming through. This header doesn't really hurt anything, but according to that same doc it shouldn't be there:
If you add the Arr-Disable-Session-Affinity header to disable the affinity cookie, ARR will not set the cookie, but it will also remove the Arr-Disable-Session-Affinity header itself, so if your process is working correctly, you will see neither.
So...how do I get it to remove the header, too?
if you have added the Arr-Disable-Session-Affinity custom header as below in your Azure Web App web.config, then it is a correct behavior you still see the Arr-Disable-Session-Affinity header with value set to true and the ARR cookie removed in your HTTP response. I think it's an incorrect statement in the reference blog you provided which stated that the Arr-Disable-Session-Affinity header will be removed.
If you want to remove that header then the cookie will present, it's mutually exclusive.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Arr-Disable-Session-Affinity" value="true" />
</customHeaders>
</httpProtocol>
The article you refer to doesn't say specifically how to add the header so I can't tell if you did it correctly. I haven't tested but according to this article you should set it in the Application_PreSendRequestHeaders:
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.Headers.Remove("X-AspNet-Version");
Response.Headers.Remove("X-AspNetMvc-Version");
Response.Headers.Add("Arr-Disable-Session-Affinity", "True");
}

Remove Server Response Header IIS 8.0 / 8.5

How can we remove the server header response in IIS 8.0/8.5?
My current server report:
Microsoft-IIS/8.0
Microsoft-IIS/8.5
For IIS 7.0 I used the URLScan 3.1 however this is only supported for IIS 7.0 and not 8.x
There is another solution and in my opinion this solution is the best and safe.
You can use UrlRewrite module created by the Microsoft. The Url Rewrite module redirects your url and can also change your IIS server name in the response header.
You don't have to use redirect property. You can use just change the Server header value.
Here are the steps:
First, download UrlRewrite module from this link:
http://www.iis.net/downloads/microsoft/url-rewrite and install
it on your IIS server. After that, restart IIS by this command on cmd
console
iisreset /restart
Add the following item to the your web config file under the <system.WebServer> tag. You can write anything to the Value item as server name.
Finally we changed the IIS version name on the data's header. Restart IIS again. via cmd console.
Bonus: If you want to test your website to see if it is working or not... You can use "HttpRequester" mozilla firefox plugin. for this plugin: https://addons.mozilla.org/En-us/firefox/addon/httprequester/
PS: I tested it and it worked for me on the IIS server. Not on the has been created temproray IIS server by the Visual studio.
It is possible now to remove Server header from web.config starting from IIS 10.0 :
<security>
<requestFiltering removeServerHeader ="true" />
</security>
More details on how to remove all unwanted/unnecessary headers can be found here.
Please note that this hides server header from the "application", as do all the other approaches. If you e.g. reach some default page or an error page generated by the IIS itself or ASP.NET outside your application these rules won't apply. So ideally they should be on the root level in IIS and that sill may leave some error responses to the IIS itself.
Note there is a bug in IIS 10 that makes it sometimes show the header even with the modified config prior to 2019.1C. It should be fixed by now, but IIS/Windows has to be updated.
Add the below code in Global.asax.cs:
protected void Application_PreSendRequestHeaders()
{
// Remove the default Server header
Response.Headers.Remove("Server");
// Optionally, add your own Server header
Response.AddHeader("Server", "My-App/1.0");
}
This has been tested to work under IIS 8.5 and 10.0.
Unfortunately most of the recommendations you will find online for removing the "Server" header in IIS will not work for IIS 8.0 and 8.5. I have found the only working option, and in my opinion, also the best, is to use an IIS Native-Code module.
Native-Code modules differ from the more common Managed modules, as they are written using the win32 APIs rather than ASP.NET. This means that they work for all requests (including static pages and images) rather than just requests that past though the ASP.NET pipeline. Using a Native-Code module, it is possible to remove unwanted headers at the very end of the request, meaning that you can remove headers (including the "Server" header) regardless of where they have been set.
Binaries and source code of an example Native-Code module for removing headers in IIS 7.0 to 8.5 are available in the following article.
https://www.dionach.com/en-au/blog/easily-remove-unwanted-http-headers-in-iis-7-0-to-8-5/
Just use clear tag in custom headers segment in web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="X-Custom-Name1" value="MyCustomValue1" />
<add name="X-Custom-Name2" value="MyCustomValue2" />
</customHeaders>
</httpProtocol>
</system.webServer>
For dynamic headers, You can use this code in Global.ascx:
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.AddHeader("Sample1", "Value1");
}
This is dead simple. Just create a custom module:
public class HeaderStripModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.PreSendRequestHeaders += (sender, args) => HttpContext.Current.Response.Headers.Remove("Server");
}
public void Dispose(){}
}
And then register in web.config or applicationHost.config if you want machine wide implementation.
<system.webServer>
<modules>
<add name="HeaderStripModule" type="MyNamespace.HeaderStripModule" />
</modules>
</system.webServer>
URLScan has been discontinued starting from IIS 7.5, since its functionalities are supposed to be available through "request filtering" option (feature added in IIS 7.5).
But the URLScan's 'Remove server header' option does not look like having any equivalent in "request filtering".
As said on this answer and this answer to you question, you can emptied the Server with URLRewrite instead, which remains available on IIS 8/8.5 (with some update required for having its UI in IIS administration console).
It turns out, looking at this blog, that URLScan can still be installed on IIS 8/8.5, if lack of official support is not an issue.
I have not tested myself. Here are the steps:
Install IIS 6 Metabase compatibility (if not already there)
Install Isapi Filters (if not already there)
Install URLScan (from download-able installer, not from web platform installer)
Configure URLScan through its ini file (by default in C:\Windows\System32\inetsrv\urlscan)
Maybe some iisreset or even a reboot should be done. URLScan should be visible in IIS among Isapi filters
In IIS Manager, at the server level, go to the Features view. Click on HTTP Response Headers. You can add/remove headers there. You can also manage the response headers at the site level as well.

Resources