MVC2 Active Directory Authentication - asp.net-mvc

I'm trying to add Active Directory authentication to a help desk system that was built years ago. Gradually, we'll be upgrading the whole system. I'm starting by creating an MVC2 application that will host the login, and then my plan is to bring current functionality into the MVC as we also add new features.
But the login is the base of the whole thing. We need auditing, so we need to know who's in the system.
I've read articles, other stackoverflow posts, and followed a couple MS walkthroughs to the letter. I was able to get it working as an ASP website, but when it's an MVC application, I can't seem to get it. The ASP application required adding extensive methods, and everything I read makes it sound like MVC should be much simpler.
Here are my IIS settings and the mods I've made to my web.config:
IIS Authentication
Anonymous: Disabled
ASP.NET Impersonation: Disabled
Forms: Enabled
Windows: Disabled
...
...
I keep getting the following error:
HTTP Error 401.2 - Unauthorized
You are not authorized to view this page due to invalid authentication headers.
End goal is to authenticate the user at the home page. If they can't be authenticated, force the login.
EDIT: Enabled Anonymous Authentication
I enabled Anonymous Authentication to see if any underlying errors might be the source of the problem. I got the following error:
The container specified in the connection string does not exist.
It's finding the error in the definition of MyADMembershipProvider.
<add name="MyADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" />
I changed my connection string to the following:
<add name="ADConnectionString" connectionString="LDAP://server.domain.com"/>
That did successfully redirect to the login page, but it didn't authenticate me automatically. And when I set Anonymous to Disabled again, I was back to the original error.
I think I'm missing some essential knowledge here that I'm not getting from the materials I'm reading.
EDIT: Authentication not working at all
I thought it might be worth adding that authentication isn't working at all.MembershipService.ValidateUser always returns false.

I think the solution is in the Authentication type. Originally, I was using the following:
IIS Authentication
Anonymous: Disabled
ASP.NET Impersonation: Disabled
Forms: Enabled
Windows: Disabled
And in my Web.config file I was using Forms authentication. Apparently for Active Directory authentication, the type has to be Windows.
Original:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
Revised:
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
I know this worked, but since I'm new to MVC, I could still be missing something.

Related

Protect ignored route from anonymous access in MVC.NET

Like the title says, I want to protect a directory from anonymous access and that directory is ignored for routing because it contains static content.
I should also mention I'm just using the out of box individual accounts identity stuff in my MVC app.
The other catch I have is that I will be hosting as an Azure web app.
Ignore route looks like:
routes.IgnoreRoute("Cordova/{*pathInfo}");
That works just fine.
I thought I could just add a location exclusion in my web.config:
<location path="Cordova" >
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
With just that, I can still access the content as an unauthenticated user, so that isn't it alone.
Then in the Web.config, system.webServer->modules section I added:
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
Now it will deny access to the directory (when using the location element above), BUT it will not allow access to any authenticated user.
I saw a few other suggestions that involved tweaking IIS settings or local directory permissions, but since I'm hosting in Azure, that is not an option for me.
UPDATE
I implemented forms authentication in the web config, and manually added the FormsAuthentication calls in my Account controller. AND it works!
So I'm guessing the web.config deny="?" in the location element is only enforceable with forms auth??
Now I have the forms auth mixed in with the OWIN cookie auth stuff. I thought one used the other (what happened to app.UseFormsAuthentication?) but its not looking that way. I'm making a mess.
How should I be doing this?
UPDATE2
And in doing so now my WebAPI security is broken.

Azure Active Directory Organizational Authentication Mechasnim

I have recently started on developing an ASP.NET MVC web app which uses organizational authentication on Azure Active Directory.
I followed this tutorial: http://www.asp.net/identity/overview/getting-started/developing-aspnet-apps-with-windows-azure-active-directory
And I managed to deploy the application and it runs correctly.
However, I'm still unsure of the underlying working mechanism of the Federation WS used to provide the Active Directory organization authentication.
The application immediately redirects the users to the Microsoft login site when the website is run before rendering the home page. I could not find any piece of codes in the application that make this happen. I tried to comment out the IdentityConfig method in Global.asax but the redirection is still happening.
I would like to know when and how does the application start the authentication process and is it possible and safe to suppress the authentication process until the Sign In hyperlink is clicked by the user.
For adding AD authentication to ASP.NET WebApps/VNext you can use the new ADAL Library, there are many samples available here https://github.com/AzureADSamples. You can use this for example: https://github.com/AzureADSamples/WebApp-WSFederation-DotNet, this is completely driven by user actions.
I found out that the solution is pretty easy. Just remove:
<system.web>
<!-- remove/comment out
<authorization>
<deny users="?" />
</authorization>
-->
</system.web>
in Web.config. This will tell WSFederationAuthenticationModule not to execute the redirection event and allow anonymous users in public pages.
Apply [Authorize] attribute to the action or controller when authentication is needed if you are developing in ASP.NET MVC.
If you are developing in ASP.NET Web Form, add the following:
<configuration>
<!-- Add the following configuration-->
<location path="Admin">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
</configuration>
The above configuration will force the users to login Azure Active Directory in order to access the relative location path of 'Admin' in your web application (e.g. http://localhost:8080/Admin).

HTTP Error 404.15 - Not Found ...because the query string is too long

I've checked lots of posts about this error but not been able to fix the problem yet.
I have simple MVC5 website built in VS2013 running on Windows 8 pro. When the site was created the option for individual accounts was selected. I now need to enable windows authentication so that only AD account users can use the website and also authorisation so that I can limit access to certain views / controllers to particular AD groups.
Having selected the web project within VS I have updated the properties window (F4) so that Anonymous Authentication is set to disabled and Windows Authentication is set to Enabled.
The web.config for the project now contains the following sections:
<system.web>
<authentication mode="Windows" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
</modules>
</system.webServer>
I access the site from IIS or F5 I get the error: HTTP Error 404.15 - Not Found
The request filtering module is configured to deny a request where the query string is too long. I notice that something has looped to give a ReturnUrl which is a repeating long concatenation within the query string.
Within the IIS\Authentication section, I have set to disabled "Anonymous Authentication, ASP.Net Impersonisation, and Forms Authentication". Within the section IIS.Net Authorization Rules I have set to Deny "Anonymous Users" and Allow "All Users"
Where am I going wrong?
The only time I've personally run into this issue is when I accidentally added [Authorize] to a child action that was used in the layout. Adding [Authorize] to your sign in action would have the same effect or simply neglecting to add [AllowAnonymous] on your sign in action, when the controller it is in has [Authorize] on it. Long and short, this is being caused by something requiring authorization on the actual sign in page, which then causes you to be redirected to the sign in page, which needs authorization, causing you to be redirected to the sign in page, etc.
tl;dr
Make sure your sign in / login action does not have [Authorize].
Make sure your sign in / login action does have [AllowAnonymous].
Make sure no child actions used in your layout or sign in page have [Authorize] or have [AllowAnonymous] if they are in a controller decorated with [Authorize].
I got this error when I enabled Windows authentication. I wanted to authorize the user based on Windows login and I do not want login page in my application.
I got the error fixed by adding the below in my Web config file.
Under the tag system.web, changed authentication mode="None" to authentication mode="Windows"
Under tag appSettings, added add key="owin:AutomaticAppStartup" value="false"
You may have a function in startup that redirects you to a login page. You must disable it.
I created the project by default authentication method which creates an account controller and its dependencies. When I changed the authentication method to Windows, the mentioned error was raised.
What I did was comment out the ConfigureAuth(app) function in my Startup.cs file to resolve the issue.
I had the same problem..
Check under Project Properties..
Anonymous Authentication=False
Windwos Authentication=True
We ran into a similar issue and our authorize filters were correctly implemented. I am leaving this here in case someone else runs into same problem with IIS 10.
After working with Microsoft support, we determined that the .Net Authorization Rule was not enabled on the server level.

asp.net mvc my web application is auto logout

I have created an asp.net mvc web application, it's working fine on localhost but when I upload it, users will get logged out automatically while they are working.
I used:
FormsAuthentication.SetAuthCookie(dbuser.FName, false /* createPersistentCookie */);
and in Web.config:
<authentication mode="Forms">
<forms loginUrl="~/home/login" timeout="2880" />
</authentication>
I tried a lot of things but didn't find a solution. How can I prevent the auto logout from happening?
Ensure that where ever you are hosting it is hosting it as a single instance or handling the session state in an instance-independent manner - ASP.net does not automaically handle session transfers in web gardens or farms. The moment your client hits the other server, they will be logged out.
If you are hosting it on AppHarbor with two web workers for example, you will need to handle the state setup yourself.
Have you tried setting:
Session Timeout Value
<system.web>
<sessionState mode="InProc" timeout="20"/>
</system.web>
At last I have to change my whole coding converting into cookie base user module

How to secure Elmah.axd?

We're using Elmah as our error logging system for an app that will be going into production soon. It's extremely useful, but if it goes into production like this anyone in the world access the error log because all they have to do is visit ourdomain.com/elmah.axd.
This is obviously not ideal. I originally intended to restrict access to that page only to IP addresses within our company, but now our SysAdmins are saying that's not possible. So I'm asking here how can I prevent access to this resource?
We running an ASP.NET MVC app on IIS 6.
The typical scenario for securing elmah.axd is allowing only some authenticated user to be able to access it. But if your site doesn't use any authentication at all this might not be applicable.
Here's what I would recommend you:
Disable completely the elmah.axd handler on your main site
Configure elmah to write the logs to some shared data source (like a shared file, SQLite database or even SQL Server)
Configure a second site in IIS, probably on another network or server, which has only elmah installed and which points to this same shared data source. Now you would always use the second site to read the logs. Obviously the second site would only be accessible to you.
If you decide to use SQL Server you could even read the logs of multiple applications running on multiple web servers in a farm from within a single internal application accessible only to you.
I found this is most acceptable for MVC applications:
http://www.beletsky.net/2011/03/integrating-elmah-to-aspnet-mvc-in.html
You can point the elmah http handler to another url (for example "Secure/elmah.axd") in web.config. You can secure the url as any other asp.net page in the web config.
<httpHandlers>
...
<add verb="POST,GET,HEAD" path="/Secure/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<location path="Secure" > <!-- secure the host.com/Secure path -->
<system.web>
<authorization>
<deny users="?" />
<!-- Or anything else... -->
</authorization>
</system.web>
</location>
We are successfully using this approach on IIS7 using active directory membership providers, and it works great. I am not sure if it works on IIS6 though.
If you're using ASP.NET Membership, it's pretty easy to restrict access to the elmah.axd HttpHandler for anonymous users and only allow logged in users in an "Administrators" group. I've done it like this:
<configuration>
...
<location path="elmah.axd">
<system.web>
<authorization>
<allow roles="Administrators"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
</configuration>
Anybody who's logged in AND member of the "Administrators" role can access the page now.
Here are some useful links:
Securely Implement ELMAH For Plug And Play Error Logging
Securing Error Log Pages
If your intention is to disable remote users from accessing it, simply change the value of <security allowRemoteAccess="yes" /> to <security allowRemoteAccess="no" />
I used IP Restrictions from the IIS 7 configuration. By default, you can't simply apply it in <location path="elmah.axd"> because it's locked on the parent configuration level. As such, I created an empty folder "logs" and applied restrictions in IIS to this folder, then modified the location path for the elmah.axd file. That's it! You have remote access to yourdomain.com/logs/elmah.axd, but only from specific IPs.

Resources