How do I get AD user when using ASP.Net Identity - asp.net-mvc

I am trying to get details of current windows (AD) user in my mvc 5 asp.net vb.net intranet site.
When I started this project, I set my authentication to individual accounts assuming that I can still get windows user information. But I have had no luck. I can get this information when I am using visual studio in debugging. But this information is replaced by the identity name of apppool in IIS.
My intranet site is currently set to use the following config.
<authentication mode="Windows" />
<authorization>
<allow users="*"/>
<!--<deny users="?"/>-->
</authorization>
My application is set to use anonymous and windows authentication. If I turn off anonymous, I start getting query string too long. It starts going in infinite loop when trying to create a return url. This is really annoying.
Anyways. For me, the concept was: If the user is windows AD user, they can get to my log in page and if correct credentials they can use the site else get kicked out. So a bit like a two factor authentication.
I have settled for allowing anonymous in favour of getting ad information and then based on that I can either deny or allow access. I intend to put this information in my login controller where signinstatus.success = true.
I have scoured the internet in trying to find a decent enough solution to try and get this hybrid to work but I am struggling for clarity. In some cases people just want to plug their own tools.

AllowAnonymous is necessary when you have a precursor to authorization, i.e. a login page the user must submit. If you don't allow anonymous users to access this page, then there's no way for them to actually login to become authorized to view the page (hence your infinite redirect).
ASP.NET Identity and Windows Auth are distinct and incompatible authorization schemes. You cannot use both simultaneously in the same application. You can however, use ASP.NET Identity and add a custom authentication/authorization layer that utilizes an LDAP connection to check credentials against AD. In other words, if you want to use AD, you have to add a manual integration of that.

Related

asp.net mvc windows authentication - users logged in as different users

We have asp.net mvc web application, hosted in IIS with Windows authentication enabled (we are using active directory to authenticate users).
At some point (in production), users found themselves logged in using different users, the login usually done when user login to their laptops/PCs in the organization, so it is expected the website to always show their logged in user to the PC/laptop cause that is their identities.
For IIS, we are storing session state in Sql server, and we are maintaining sessions using HttpContext.Session in the application.
I need some guides on how I can track the source of the issue. Is there a tool or what code I can share with you that might help ?
Thanks!
Make sure that:
You have “Integrated Windows Authentication” (formerly called NTLM
authentication) enabled within IIS for the application you are using.
You should then add a web.config file to the root directory of
your ASP.NET application that contains an <authentication> section
which sets the mode to “Windows”.
You should also then add an <authorization> section to the same
web.config file that denies access to “anonymous” users visiting the site. This will force ASP.NET to always authenticate the
incoming browser user using Windows Authentication – and ensure that
from within code on the server you can always access the username and
Windows group membership of the incoming user.
The below web.config file demonstrates how to configure both steps described above:
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
Troubleshooting ideas...
For seeing the error, I would make sure you are showing the current user HttpContext.Current.User.Identity.Name; on each page. Refresh the page and make sure the user doesn't change. Go to other pages and do the same. Clear all cookies and application state in the browser, close the browser, then re-open the browser and go back to the site. You should still be logged in as the same user every page and every browser session. If this is intermittent, you may have to repeat this a few times to reproduce the error.
Does this every happen when running local IIS Express on developer machines? Does it ever happen in other environments (test, staging) where the code is deployed? If not, what is different about production?
Is there a proxy server between the users and the production web server? Or even some of the users, like if they come in through VPN?

Identity Impersonation with ASP.NET 4 MVC not working as expected

I am in the process of building a Intranet MVC 4 application for our analysts. The goal is to allow internal users access to this application without having to sign on given they are part of our internal network. When they access the application I want to be able to capture their windows user name and check against the active directory using LDAP and retrieve the department they belong to and display the relevant details on the screen. Based on the advice from different fora, I have chosen Windows Authentication for this application and I was able to test the app successfully running from Visual Studio. The trouble I am having is when I deploy this to our UAT server running IIS 7.5.
<authentication mode="Windows">
</authentication>
<identity impersonate="false" />
This is the current state of my Web.config file. Irrespective of whether impersonate is true or false, the application seems to not capture the windows username of the browser from which the application is accessed. Is
impersonate = true
required for this at all? In the Welcome message on the homepage, I always see the windows user name of the computer where the application is hosted/IIS is running. I have tried a wide variety of ways to capture the Windows User name of the incoming user request.
string name = System.Web.HttpContext.Current.User.Identity.Name;
string name = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name;
string name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
string name = System.Web.HttpContext.Current.Request.ServerVariables["LOGON_USER"].Name;
etc. I also looked into several other posts here like this. But I am unable to get it to work. I am afraid that I am trying to achieve this by accident rather than really understanding what is going on? Could someone please guide me in the right direction?
No, you misunderstand the purpose of impersonation.
First, Impersonation is no longer supported in IIS 7 or greater running in integrated mode.
Second, the purpose of impersonation is to change the "user" the worker process runs under at runtime, specifically to allow access to filesystem or database resources as that user. It has nothing to do with authentication in general, and is not particularly useful for most web applications.
You want to use Windows Authentication, however you should know that this will only work with Internet Explorer. It will also only work with servers that are joined to your domain, and do not have any intermediary Kerberos authentication issues. (these are often known as "double hop" problems). Other browsers do not, by default, provide Active Directory account information automatically, although some may be configured to allow it to do so, others do not.
If you are using a properly configured server with Windows Authentication, and you are using a browser that supports ActiveDirectory Kerberos ticket passthrough, and there are no network issues that would cause problems with this passthrough, then you can use HttpContext.Current.User.Identity.Name to get the users name.
Don't use LogonName or anything like that, as those will just give you the worker process, not the authenticated users name.

Implementing single-sign on in ASP.Net Webforms and MVC

I have an existing WebForms application and we're now creating a new MVC application. They both authenticate using our own custom provider, using the same database.
I can successfully log in in each application separately using the same credentials, but what I now want is to implement a single-sign on (ie: if the user is already logged in in app1, app2 would automatically detect the user's settings and identify him as being logged in).
I have done my homework and read the references here, here and here, amongst others.
So far I have done the following:
Set the same machineKey on both sites:
Set the same forms auth on both sites:
Despite all of this, I haven't managed to get SSO working. I have managed 'Single-sign off', whereby when the user signs off one site, he's signed off from the other.
Is there anything I'm missing?
I would like a configuration-only solution, that does not require me to do any coding.
I am answering my own question just for closure's sake.
The reason why my my SSO was not working is because the main, existing website has its own cookie and session manager, and does not play by the rules of Forms authentication. It calls
FormsAuthentication.SignOut();
Shortly after login has completed.
I tried the configurations mentioned above with 3 different websites, a mixture of MVC and WebForms, different pipelines (integrated vs classic), with our custom membership provider, and it all worked marvellously.
So the steps defined above should work as long as your application does not do funny things with forms authentication.

Silverlight, SSL, HTTPS, WCF, MVC, and Forms Authentication

I have an MVC 3 website that is using Forms authentication. The user logins and navigates to a Silverlight 5 application. The Silverlight app is calling a Silverlight-Enabled WCF service on another port. Because one of my requirements is to use Https/SSL, I decided to move the WCF services into a "Services" folder in my MVC application.
To see if the service is working, I typed in the address of my service. I got an error message stating my service requires anonymous access, but the website is specified to use forms authentication. So, I removed my mexHttpBinding in my web.config for my service and added authenticationScheme="Negotiate" to my httpTransport of my binding. (I'm not to https yet).
Now, I get a 302 and am redirected to the log-in page. It seems that my service is suggesting i'm not logged in. So, I added
routes.IgnoreRoute("{resource}.svc/{*pathInfo}");
and
routes.IgnoreRoute("Services/");
but that hasn't made a difference. I think the service says i'm not authenticated, but I'm certain I am.
Can someone explain what I'm doing wrong?
All of this works when I debug on my localhost, but I can't access the service when I deploy to a server.
Edit
I may have found my answer. I turned on anonymous access for my website in IIS and changed the httpTransport's authenticationScheme to the default (Anonymous). I then added
<authorization>
<deny users="?"/>
</authorization>
along with
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
which seems to be requiring the user to be authenticated in order to access the service. I am now going to check my silverlight application to make sure it can reach the service and get/post data. This was all in a test application, so I'll have to change my real application accordingly. Then, I'll tackle ssl/https.
Does all this sound right?
EDIT 2
I had to ensure mex was enabled and aspNetCompatibilityEnabled was set to 'false' to get the conctracts to update in my silverlight app. But after updating my services, I set the aspNetCompatibilityEnabled to 'true', and everything appears to be working.
I hope I'm still headed down the right path...
I ended up setting up IIS to add the webservice as a website under the parent website. Then, I used the Location tag in the parent site's web.config to implement forms authentication on the webservice.

Managing security rights based on User.Current.Name in ASP.NET MVC

I am using ASP.NET MVC to build a web application.
In the main screen of logged-in user, I am using User.Current.Name to determine logged-in user identity, this is mapped to ID of a domain model data that is related to the current user. No one else should be able to see or edit this information (say his profile).
I am using membership and roles to ensure that only logged in users in particular role are able to invoke this action (Home action of UserController in this case)
There is going to be no HTTPS for this application when it is deployed.
Is this approach considered a safe approach?
Is there any chance for malicious user to fake his identity to ensure that User.Current.Name returns a different name?
Is there any additional configuration required to ensure that no one can "steal" the authentication cookie of another user?
EDIT: Standard Forms authentication is used.
OK so, setting HTTP sniffing aside because you won't be using SSL, the main problem point is the authentication cookie.
The forms authentication/roles cookie isn't encrypted by default, it is only signed against tampering. You can encrypt it using
<forms protection="All" ... />
This will use the machine key specified in machine.config or web.config to encrypt - so if you want the cookies to live across app recycles you will need to set a specific machine key.
You should also look at not persisting cookies (i.e. no "Remember me" option) and ensure that secure pages that require authenticated access are placed in subdirectories/controllers that separate from the anonymously accessible pages.
You may also want to reduced the cookie lifetime, which can reduce the amount of time a stolen cookie lives for.
<forms
timeout="10"
slidingExpiration="true"... />
You should also be encoding all your output to web pages to stop Cross Site Scripting, as this is the major way of cookie stealing. The ASP.NET cookie is HTTP-Only, which means it should not be served up via javascript, however not all browsers implement this (Safari doesn't).
As long as you have set the machineKey property in web.conrfig, the cookie is encrypted on the server side, and no one can fake that information. However, since the standard authentication mechanism in ASP.net MVC is regular Forms authentication, you should enable SSL so that no one can sniff the username and password when logging in.
Another approach is to use a different authentication mechanism. This could be windows authentication, kerberos, use of client certificates etc.

Resources