Umbraco - Disabling ASP.NET SessionState on selected pages - asp.net

I have a fairly large Umbraco instance containing a mix of marketing pages and web applications.
About 10% of the Content node pages are web application pages. I want to disable SessionState for the remaining 90% of pages which don't need it, in order to improve performance and avoid contention. We are using SQL Server sessions.
Is there any way to do this? As far as I've been able to find out, the only way to disable SessionState on a per-page basis is to include EnableSessionState="False" in the .aspx #Page declaration. But as Umbraco generates virtual .aspx pages, I can't see any way in which to do this.
There doesn't appear to be any way in code to effect it either.

Since you seem to be using nested webforms master pages in Umbraco (rather than MVC) you are left with one option since the Masterpages don't have the public property 'enablesessionstate'
As far as I know you are left with one option which is to handle the sessionstates in the web.config
There are two scenarios, implicit and explicit
Explicit exclusion
<!-- globally enbabled sessionstate -->
<system.web>
<sessionState mode="On" />
</system.web>
<!-- disable on specific paths -->
<location path="path/whatever">
<system.web>
<sessionState mode="Off" />
</system.web>
</location>
<location path="otherplace">
<system.web>
<sessionState mode="Off" />
</system.web>
</location>
Implicit
<!-- globally disabled sessionstate -->
<system.web>
<sessionState mode="Off" />
</system.web>
<!-- enable on specific paths -->
<location path="path/whatever">
<system.web>
<sessionState mode="On" />
</system.web>
</location>
<location path="otherplace">
<system.web>
<sessionState mode="On" />
</system.web>
</location>

If you're using web forms, you could potentially hook into the page loading event and check the page template to then set the session state on or off?
Which version of Umbraco are you using?

Related

asp.net cookieless for certain pages on site

To avoid adding cookie consent acceptance, I would like to disable cookies for certain pages in my asp.net site. I know I can add this to the config:
<configuration>
<system.web>
<sessionState cookieless="true" />
</system.web>
</configuration>
But is it possible to specify that only certain pages (in matter fact only one page) to be cookieless?

Url Authorization with MVC and ASP.NET Identity

I want to secure specific folders and resources in my application that are outside of the routes for my mvc application. I want these resources to only be available to authenticated users (which role is not of concequence as long as they are authenticated).
Initially it seemed that the UrlAuthorizationModule would be the answer. I followed this article, Understanding IIS 7.0 URL Authorization, and I can get the module to work in the sense that it responds to the configuration elements in the web.config.
My current problem is that I think it is enacting the rules based on the anonymous user in IIS and not the authenticated user in asp.net identity.
Test Environment
I use a standard html file for testing instead of trying to load a script as this would also be loaded outside of the MVC pipeline.
In Visual Studio 2015.
New default .net 4.6.2 web project
MVC template
Authentication = Individual User Accounts
IIS 8 (for testing outside Visual Studio)
Authentication -> Anonymous Authentication (enabled)
Add to web.config
<configuration>
...
<location path="Data">
<system.webServer>
<security>
<authorization>
<clear/>
<add accessType="Deny" users="*"/>
<add accessType="Allow" users="?"/>
</authorization>
</security>
</system.webServer>
</location>
...
</configuration>
Add to folder structure
/Data/Protected.html // this file just has some basic Hello World content to display so you can see if it is loaded or not.
Observed Results
With this configuration everything in the Data path is always denied, it does not matter if the user is authenticated or not.
The same is true if I switch the 2 lines for Deny and Allow in the web.config.
If I completely remove the line with Deny then access is always allowed even when the user is not authenticated.
If I add a role and use roles with the role name instead of users attribute the role is also completely ignored.
Now What?
What am I missing? How can I get the Url Authorization module to work with MVC/WebAPI and ASP.NET Identity Individual user accounts or is this simply not doable?
I am open to alternative ideas as well, maybe the answer is to write a custom HttpModule or HttpHandler?
Side notes
Why & Specifics
These resources are javascript files, in short only a portion of the scripts should be available to unauthenticated users. There are 2 directories in the root, one for the authenticated part of the app and one for the non-authenticated part of the app. The reason for this has nothing to do with user authorization or security in the application, it is to limit the exposed surface area of the application to non-authenticated requests.
[TL;DR;]
Go to "Complete root web.config" section to see the needed web.config setup.
Test this in incognito-mode to prevent browser caching issues!
And use Ctrl+F5 because scripts and html files get cached.
First deny access to all anonymous users in the root web.config.
<authorization>
<deny users="?"/>
</authorization>
The web.config here allows one folder to be publicly accessible. This folder, in my example here, is called css and sits in the root of the MVC application. For the css folder I add the following authorization to the root web.config:
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
You can add more of these location paths if you want more public folders.
While all other files will not be accessible until the user logs in, the css folder and its contents will always be accessible.
I have also added a static file handler to the root web.config, This is critical as you want the request to be managed by the asp.net pipeline for the specific file type(s):
<handlers>
<add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
Complete root web.config
<system.web>
<authentication mode="None" />
<authorization>
<deny users="?"/>
</authorization>
<compilation debug="true" targetFramework="4.6.2" />
<httpRuntime targetFramework="4.6.2" />
</system.web>
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
</modules>
<handlers>
<add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers>
</system.webServer>
ASP.NET by default will only apply the allow and deny rules to files handled by the managed handler. Static files are not managed by the managed handler.
You could also set: (Don't do this, if not really needed!)
<modules runAllManagedModulesForAllRequests="true">
With runAllManagedModulesForAllRequests="true" all the HTTP modules will run on every request, not just managed requests (e.g. .aspx, ashx). This means modules will run on every .jpg ,.gif ,.css ,.html, .pdf, ... request.
One important thing
You don't have to add the UrlAuthorizationModule to the modules section as it is already part of the ASP.NET pipeline. This means, it will run only for managed files, not static!
If you now remove and then re-add the UrlAuthorizationModule to the modules section, it will run under precondition "integratedMode" and not under "managedHandler" anymore! And will therefore have access to static files.
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
If you set the precondition to managed:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />, then the UrlAuthorizationModule will not restrict access to static files anymore.
You can test this by accessing a script file in the scripts folder successfully while being logged out. Hit Ctrl+F5 to make sure you get a fresh copy of the script file.
Difference between ASP.NET UrlAuthorization <--> IIS URL Authorization
It is important to keep in mind that the managedHandler precondition
is on the ASP.NET UrlAuthorization module. The precondition tells you
that the URL authorization module is invoked only when the code that
handles the request is mapped to managed code, typically an .aspx or
.asmx page. IIS URL Authorization, on the other hand, applies to all
content. You can remove the managedHandler precondition from the
ASP.NET Url Authorization module. It is there to prevent a performance
penality you have to pay when every request (such as a request to
.html or .jpg pages) would have to go through managed code.
P.S.: Some web.config attributes are case sensitive!

Turn on and off Session in ASP.NET

Is there a way of turning on and off the session cookie in ASP.NET without using the <#PAGE construct? A way to overrule the construct?
I want sometimes to have session enabled on the page, sometimes disabled. I don't want to have to keep recompiling the website to enable or disable the session. In php you could turn on session by open_session() , I wonder if there's an asp.net equivalent. I'm looking for a way to enable the session in code.
If someone visits the Login page, the session is then enabled for the whole otherwise, it is not enabled and the site is sessionless, cookieless.
You must set the Off mode in the sessionState of the web.config file, in this way it disable the session of the application but if you want to disable the asp.net cookie but still track of the session you could use the cookielessoption.
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<sessionState mode="Off"/>
<!-- or -->
<sessionState cookieless="true"/>
</system.web>
</configuration>
Guess you can do it in web.config: https://msdn.microsoft.com/en-us/library/h6bb9cz9(v=vs.71).aspx

Blocking static content in MVC 3

What's the best way to prevent users from downloading specific files in my Content directory?
Should I add a Web.config to /Content, like I already have in /Views?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpHandlers>
<add path="SecretFolder/*" verb="*" type="System.Web.HttpNotFoundHandler" />
<add path="SecretFile.pdf" verb="*" type="System.Web.HttpNotFoundHandler" />
</httpHandlers>
</system.web>
</configuration>
Or should I create a custom routing rule?
Or is there an even better way?
This is exactly what the <authorization> element is for in web.config. This will give you granular control over what users can see which files. You can provide as little or much control as you need.
<location path="SecretFolder">
<system.web>
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
However, this assumes that you are implementing ASP.NET authorization using IPrincipal, which I would recommend if you need this sort of control over your content.
Basically exactly as you have above - AS LONG as you don't have another route that would get to this via a controller. Judging from the file types and structure this doesn't seem to be the case (a concern is that you have two routes going to the same file - and using the authorization elements in a web.config is recommended against in MVC specifically for this reason)
You want to use exactly what is already used by MVC.
See the integration of "HttpNotFoundHandler" into your web.config at (I know.. you already have it) :
http://completedevelopment.blogspot.com/2011/06/using-views-outside-of-views-or-other.html
This is how content inside of your /Views folder is already blocked - so this is already 'mvc-ish'

asp.net authorization

In my ASP.NET Application, I have an asmx Web Service which is in it's own directory. For this WS I have set the basic authentication under IIS 6.0 and put the separate web.config for that folder, with following nodes:
<system.web>
<authorization>
<allow users="domain\username"/>
<deny users="*"/>
</authorization>
</system.web>
With settings like these I get
Error message 401.2.: Unauthorized: Logon failed due to server configuration. Verify that you have permission to view this directory or page based on the credentials you supplied and the authentication methods enabled on the Web server. Contact the Web server's administrator for additional assistance.
when webmethod is invoked with SOAPUI or with browser. If I remove the deny node, any valid user in domain can get a web service response.
Any suggesstions how to make it work for one domain user only?
Maybe I should mention also, that authentication in main web.config is set to "Windows".
updated:
Oops, I overlooked the fact that you have a parent involved, my fault. Once permission defaults are set on the parent, you can just setup per-user access to the child web service/app.
The tightest configuration I could setup was the following.
For the parent, I used this barebones setup (nobody is allowed in):
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true" />
<authentication mode="Windows" />
<identity impersonate="true" />
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
Then for the child (web service, in your case), I used this setup (only the DOMAIN\username principal is allowed in):
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<authorization>
<allow users="DOMAIN\username" />
</authorization>
</system.web>
</configuration>
This resulted in no access at the parent level, but only the given user at the child (web service) level. Also, as you mentioned, setting the authentication mode doesn't work on the child web.config.
Without setting up at least one allow entry at the child web.config, though, nobody can get in, as the parent's deny entry takes precedence.
original
Your settings work for me, but I believe you are missing a few elements.
Try including the impersonation element, make sure the authentication mode is set to Windows, and if deploying for IIS, make sure the IIS location has anonymous access off.
Try the following barebones config, with debug on or off as needed:
<?xml version="1.0"?>
<configuration>
<appSettings />
<connectionStrings />
<system.web>
<compilation debug="true" />
<authentication mode="Windows" />
<identity impersonate="true" />
<authorization>
<allow users="DOMAIN\username" />
<deny users="*" />
</authorization>
</system.web>
</configuration>

Resources