all requests to umbraco site redirect to login page - forms-authentication

I just took my local, functioning umbraco installation and copied it over to the testing environment.
Suddenly ALL requests to my umbraco site, meaning css, javascript etc redirect to the login.aspx page. So the website is non-functional, unless you login. If you manage to login using the no-css form, then everything is back to normal.
Web.config says
<authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" timeout="120" />
</authentication>
<authorization>
<allow users="*" />
</authorization>
Changing * to ? makes no difference. What could be the matter here? My setup is 2 configuration mirroring IIS7 web servers, looking at a common UNC path.

I think you should check permissions setting of your environment, because if you get redirect for all resources, even for static files - usually it is common permissions problem.
/install/default.aspx?installStep=validatePermissions
or for 4.7+
/install/?installStep=filepermissions
http://our.umbraco.org/wiki/reference/files-and-folders/permissions/perform-permissions-check

It can be a issue with file permissions. As a temporary solution try and set all files to "Everyone" - Modify.

All paths are only accessible with authentication, so you have to exclude js and css from authentication in your web.config, e.g.:
<configuration>
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>

You need to specify allow users="?" to allow anonymous users.
Check also the section membership...
My web.config contains:
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Another Type" passwordFormat="Hashed" />
<add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers>
</membership>
You need to:
Create a login page (like any other ASP.NET site).
Create records in
"Members" section (at least one member type, member group and
member).
Define the restricted access on content nodes (menu "Public
access").

I recently experienced this also on a test Umbraco site. Discovered it was owing to the files attempting to access being stored on the disk encrypted (using Windows 7 in my test environment).
Fixed by selecting all site files and folders in Explorer, Properties, Advanced (on General tab), uncheck "Encrypt contents to secure data". Resources could then be accessed on the Umbraco without any authentication redirects.

Related

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!

IIS URL Authorization check in ASP.Net

I have an ASP.Net web forms app running under IIS 7+
The entire app is currently secured using Windows Authentication and URL Authorization, configured in the web.config via IIS. The .NET doesn't care who the user is, there are no profiles or roles or anything at the moment.
<system.web>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AppXUsers" />
<deny users ="?" />
</authorization>
</system.web>
I wish to add an additional page (in a subfolder), which will be accessible to subset of users, so I would modify the web.config like so:
<location path="mySubFolder">
<system.web>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="AppXPowerUsers" />
<deny users ="?" />
</authorization>
</system.web>
</location>
The client is free to then add or remove AD groups as they see fit.
However, as it stands users who are in the AppXUsers group but not in the AppXPowerUsers group still get shown links to the pages in mySubFolder. When they click the links they get access denied as it should be.
Is there any way I can detect whether or not the current user has access to "mySubFolder"?
I feel it would be a bit overkill to introduce User/RoleManagement at this stage - the application has no need to store any information relevant to users and it doesn't care who the user is beyond "can they access this page or not", which is currently handled at the IIS stage.
Take a look at this: http://msdn.microsoft.com/en-us/library/system.web.security.urlauthorizationmodule.checkurlaccessforprincipal.aspx
which is referenced here:
Determine if user can access the requested page?
UrlAuthorizationModule.CheckUrlAccessForPrincipal requires that the authorization rules are set in <system.web><authorization>
If you're introducing this into your web.config, though - why are you reluctant to use it in code?
Another way to check would be:
Context.User.IsInRole("somerole")

ASP.Net 4 Forms Authentication in IIS 7.5 - Default Document No Longer Working

I've recently migrated a web app from .Net 3.5 to .Net 4 and changed the app pool to Integrated mode in IIS 7.5. This app has 2 parts: the first is open to the public and the second is by login only. I use forms authentication for login which is configued thusly in the root web.config:
<authentication mode="Forms">
<forms loginUrl="~/private/login.aspx" protection="All" timeout="20" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="~/private/default.aspx" cookieless="UseCookies" enableCrossAppRedirects="true" />
</authentication>
In the root web.config I have the default authorization to to deny unauthenticated users, thusly:
<authorization>
<deny users="?" />
</authorization>
BUT I have the setting below configured in the root web.config to allow everyone to see the welcome page:
<location path="Default.aspx">
<system.web>
<authorization>
<allow users="?,*" />
</authorization>
</system.web>
This has been working great for years but now, if I don't explicily put Default.aspx in the URL, the forms redirect module causes the login page to be served. I've verified that I have my default pages configured correctly and they are enabled in IIS7. I have also tried specifying them in web.config. I have verified that the DefaultDocumentModule is sequenced before the DirectoryListing module.
If I remove the element the problems "goes away" but the effect would be to default to allow all users and this is completely undesireable.
I'm out of ideas. Suggestions?
Thanks
I
Seems like some kind of default doc issue. If you look in IIS Manager at the site, what is in the "Default Document" list. Is it possible that something other than Default.aspx is higher in the list? If something matching this is found in your root web, it will attempt to go there first and thus be redirected to login.
Are you explicitly setting the default document in your web.config? as in:
<defaultDocument enabled="true">
<files>
<clear />
<add value="Default.aspx" />
<add value="Default.htm" />
<add value="index.htm" />
<add value="index.html" />
<add value="iisstart.htm" />
</files>
</defaultDocument>
OK, I had a Microsoft Premier Support Engineer dig into this for me. We sat down together at my workstation and went through (a) the environment and app configuration and (b) possible solutions.
He referenced this MS "Fast Publish" article which suggests that I remove the ExtensionLessURL handlers from IIS via MMC. Well, we're a huge organization with servers out the wazoo and I could not guarantee that this change would always be honored so I didn't want to do that. We tried using web.config to remove them but that did not work.
So, I showed him this solution from another StackOverflow thread (posted by Dmitry.Alk) and he said it was a good work-around for now. It works great for this particular situation.
The Fast Publish article references this hotfix A update is available that enables certain IIS 7.0 or IIS 7.5 handlers to handle requests whose URLs do not end with a period which I've got to sell to our IT "department".
I don't call what I've written here an "answer" but I wanted to share what I've come to learn in case others happen upon this thread.

Forms authentication ignored in virtual application

I have an admin site set up as a virtual applcation inside of another website.
I would like visitors to the sub directory (the virtual application) to be promtped for credentials using the same Forms authentication set up on the main parent site
Have tried all sorts of things but can't get it to work, including
Removing all <authentication mode="Forms">, <authorization>, <membership> and <roles> sections from the virtual-app web.config
Copying the same <authentication mode="Forms">, <authorization>, <membership> and <roles> sections from the parent to the virtual-app web.config
Using a virtual directory instead of virtual application
But I never get promted for credentials
Anyone know how to get this setup?
thanks
UPDATE:
Have now got it to inherit permissions from the parent, by deleting the application name in IIS (to make it a virtual directory rather than a virtual application)
However, this screws all the paths in the admin site
e.g. I get the following error
The file '/Site.master' does not exist.
So should I be using a virtual directory (which seems to inherit authentication from the parent)?
Or a virtual application (which currently doesn't inherit auth from the parent but has the correct relative paths)?
Here's the parent config
<membership defaultProvider="SqlServerMembershipProvider">
<providers>
<add connectionStringName="xxxxxxxx" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="SqlServerMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="SqlServerRoleProvider">
<providers>
<add connectionStringName="xxxxxxx" applicationName="/" name="SqlServerRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</roleManager>
<authentication mode="Forms">
<forms name=".EPiServerLogin" loginUrl="login.aspx" timeout="120"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
I needed to use a single sign on solution, as described here
http://www.codeproject.com/KB/aspnet/SingleSignon.aspx
The main point being, each site needs to use the same encryption key for the cookie values. So this machineKey element needs to be added to each site involved in the Single Sign On
How have you configured authorization?
Also, I assume you're not already authenticated in the parent site?
In the admin subdirectory you should have something like the following in your web.config (obviously you may have more information in there as well):
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
This will deny all anonymous users, but allow all authenticated users access. You can easily extend this if you are using a Role Provider to only allow certain roles:
<allow roles="Admin" />
<deny users="*" />
Note that you need the "Deny all users" in there, as the default behaviour is to allow all users. Authorization works "top down" in that it starts at the top of the list, and as soon as it finds a match, it stops processing, so if the user is in the "Admin" role, it will not get to the "Deny all users" rule.
You can also configure this in the root web.config using a <location> element.
Responding to comments
And your authentication/authorization all works in the parent site?
Could you edit your question to include (sanitised) web.config sections you've tried so we can see if there's anything obvious missing - for example, if you're using Roles to lock down the admin area, you have enabled it (<roleManager enabled="true">, defaults to false).
We do what you're trying to do quite often here.
We do it this way : The root level is a virtual application, it contains the master web.config and global.ascx. We have a normal folder, 'Admin' inside of that. Inside of that, we have a small web.config, it only contains <authorization> XML information. You'll need a login page somewhere, either the root or Admin folder.
I was a little confused in your post about whether there are three applications/directories involved (app, parent app, app's admin), or only two (app & it's admin). I'm making a critical assumption here that it's two. If you do have the three, it's going to be some more work to get this thing going.

ASP:Login Not Authenticating

I am currently learning form authentication using a SQLMembership provider. The ASP:Login control does not seem to authenticate. Here is the structure of my test site on my local machine:
~/LoginTest/
Default.aspx
CreateUser.aspx
lostpassword.aspx
web.config
/login/
Login.aspx
ProtectedStuff.aspx
web.config
In the web.config file of the LoginTest folder I have added the following nodes:
<connectionStrings>
<add name="EvgSqlConnection" connectionString="connection string" />
</connectionStrings>
<authentication mode="Forms">
<forms name="LoginTest" loginUrl="~/login/Login.aspx" path="/login"
cookieless="UseCookies" />
</authentication>
<membership defaultProvider="mySqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add
name="mySqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="EvgSqlConnection"
applicationName="LoginTest"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true"
passwordFormat="Hashed" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="mySqlRoleProvider" cacheRolesInCookie="true" cookieProtection="All">
<providers>
<clear/>
<add name="mySqlRoleProvider" applicationName="LoginTest" connectionStringName="EvgSqlConnection"
type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
In the web.config in the login folder I have the following:
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
</system.web>
</configuration>
So what this is supposed to do from what I have read is deny users access to anything in the login folder. In this case my test file is ProtectedStuff.aspx which is nothing more than a page with a label. What is currently happening is that everything seems to work except the ASP:Login control. I can currently create a new user with the ASP:CreateUserWizard on CreateUser.aspx. I can recover a new password using the question and answer set up using the ASP:PasswordRecovery control on lostpassword.aspx. I can enter the correct name and password in the ASP:Login control on Login.aspx. The only thing that doesn't seem to work is the actual authentication. Whenever I try to go to ProtectedStuff.aspx it kicks me back to Login.aspx like it is supposed to when you are not authenticated. Further, I can enter the wrong user name or wrong password and the Login control complains. I can see my user in the website administration page, I can see that the user is assigned a role.
There is no custom code behind any of these controls, all I have done is copied in the SqlProvider name into the MembershipProvider attribute of these controls. SQL Server 2000 is configured with an NT AUTHORITY\Network Service user that has aspnet_Membership Full Access checked. the config files seem to be okay, all the controls seem to be able to read and write to the database correctly, only the Login control doesn't seem to authenticate the user. What else should I be looking for?
I'd start by removing the path attribute from your Forms element:
Specifies the path for cookies issued by the application. The default value is a slash (/), because most browsers are case-sensitive and will not send cookies back if there is a path case mismatch.
If that still fails, I'd get hold of Fiddler and see what cookies are being sent back to the client and to the server after logging in.

Resources