Is it possible to programatically authenticate a user using NTLM (on asp.net)?
I would like to have control over the look and feel of the website where I would have a form that users enter their username/password. I would then query NTLM to validate the provided information and if valid, redirect them to a virtual directory?
NTLM is the protocol the web browser would talk directly to the web server (e. g. IIS) to authenticate the user, without your application being involved. That's what you want to avoid, because you want to present a "nice" logon form.
So what you need to do is: prompt for user name and password in a form, and validate these credentials against Active Directory yourself. Here is a Microsoft article describing how to do it in ASP.NET: http://support.microsoft.com/kb/326340/en-us
However please remember a few points:
Don't forget that, unlike in case of NTLM, user's passwords will be transmitted in clear text unless you use SSL to publish the web site. You never should users allow to enter their AD password on an unencrypted web site.
If some of your users were automatically authenticated (transparent login, no prompt for password at all) before, which should be the default behavior in an Intranet scenario, these users won't like your login form, no matter how nice it looks...
The default behavior in IIS6 would be that only pages generated by ASP.NET would be protected; as you would have to configure IIS to allow anonymous requests to the applications, static files could be requested by any user.
Related
I've a sub-application that I want to use windows authentication.
I want that login box pops up even in the domain when the person first reaches the page.
When I turn off Kernel-mode authentication, the login box pops up, but fails with error 401 Not Authorized after 3 login attempts.
If I turn this on, It doesn't even asks for the password,I believe this is due the computer is in the servers domain and the credentials are passed automatically.
Is there any possibility to show login form for all users, including domain users?
In the image below are my server configs.
Windows Authentication is normally handled by IIS. This is the way it works:
Client requests the page.
IIS returns a HTTP 401 response, with a header saying that it accepts Windows auth.
The client's browser automatically resends the request with the users credentials (as long as the site is trusted).
IIS verifies the user and passes the credentials to the application.
This is all designed to be seamless.
If you want the user to be prompted for credentials all the time, then either:
Make sure your site is not trusted (not in the Internet Options Trusted Sites or Intranet Sites). But you may not be able to do that.
Don't use Windows authentication. Uses Forms authentication and make a login page where the users can enter their credentials. But that means that you will have to verify the credentials against Windows or Active Directory yourself in your code.
If you use #2, then also make sure to use SSL on your site since passwords will be sent in plain text.
You can use Basic authentication. It will prompt the user for credentials and once entered, it will give you a seamless experience.
However, the disadvantage with basic auth is that it sends the password in plain text to the server. You can use SSL certificate to encrypt this information.
I have tried my best to search the web before asking this question. I've seen similar questions on stackoverflow, however, none has been answered satisfactorily for a long time now. This is one more attempt to get this recurring question answered.
The Problem
How to build an ASP.NET MVC 5 website which uses "Windows Auth" for Intranet users and "Forms Auth" for Internet users? We'd like to accomplish this using ASP.NET Identity. Moreover, we don't want to use Active Directory Groups for authorization. For Intranet users, we want to authenticate them using Active Directory and then fall back to ASP.NET Identity to manage their roles and other profile data.
It'll be nice if we don't ask the end user to choose auth method. The web app should log in intranet users seamlessly. They shouldn't even know that there is a login screen. Likewise, the internet users shouldn't be asked to enter their domain credentials. They should see form based login screen right away.
Is there any recommended way of solving this? Or could you comment if any of the following are proper solutions?
http://world.episerver.com/blogs/Dan-Matthews/Dates/2014/8/Mixing-Forms-and-Windows-Authentication/
https://github.com/MohammadYounes/MVC5-MixedAuth
http://mvolo.com/iis-70-twolevel-authentication-with-forms-authentication-and-windows-authentication/
FYI This is 2004 article, may not be helpful now:
https://msdn.microsoft.com/en-us/library/ms972958.aspx
IIS configuration
Enable Anonymous Authentication status in IIS for the whole site and Windows Authentication for some folder under root directory (for example, /WindowsLogin). In this folder place aspx file (for WebForms project) or create ApiController (for MVC project).
Site setup
On login page add button “Login with Windows/ActiveDirectory account” (in similar way as it is common practice to add buttons Login with Twitter, Facebook, Gmail, etc.). When user presses this button, they will be redirected to the page or controller in /WindowsLogin folder, which require Windows authentication. If site uses some Single Sign-On functionality, locate it in that page or controller, in other case just save Session for Windows users there. If user accessed that page or controller, they had been authenticated as Windows users already.
One of the possible ways could be creating two sites in IIS, but having the same target folder, where sources of site are located. First site is for internal users with enabled Windows Authentication mode and binding to 80 port, while second site is for external users with Anonymous mode enabled and binding to 8080 port, for example. Then, on firewall you will have to configure NAT, that all requests coming from within local network or VPN, will be redirected to local IIS server on port 80 and all requests coming from Internet, will be redirected to port 8080 of IIS server.
The term for this is Mixed-Mode Authentication. I have done this multiple times. You only need to tweak your main site. Here is how I have done it.
Keep your main MVC site as-is but run it as Anonymous vs. under Windows Auth.
Internal Site
Create a Redirect URL Site: Setup this site as Window Auth so you can pull the User ID from Active Directory. Give your users this URL and/or make it the link they click on your Intranet. Then this site calls your MVC Site and passes the user credentials (login id).
a. This can be done either via an encrypted string on the URL or encrypted value in a cookie. You can encrypt with an expiration date/time value too.
b. (Speaking from Forms Auth) Create a Forms Authentication Ticket with that user ID. Run any other login logic you have. Done.
External Site - No Changes required. Let the users login as-is.
Are you wanting to handle forms and AD authentication from one URL? I have used thinktecture (claims based auth) as the framework for WIF and marshaling various forms of authentication. However to handle if from one URL I had to handle some logic at login that associated the user to AD or Forms based. In a more recent project, this was handled at user management when we created the user account (it was associated to AD of Forms Auth). Then when the user logged in they would preface the AD domain name as part of the login. There are a number of ways to implement this, this was just one I have used. An example, instead of requiring the domain, just use the username, then check for AD or forms based flags on the username and then handle authentication accordingly
EDIT
Just an update in re-reading your question. Are the internet users and intranet users the same? If so you need to just go forms based auth across the board and manage the users in the product DB independent of AD. If they are the same then they could login prefacing the domain name to username. if you wanted to rely solely on AD.
I did a proof of concept of this some time ago, at my previous job, so the details are hazy and I don't have any code to refer to...
The requirements were:
Single URL for internal (LAN) and external (internet) access
Two types of users, people on the domain and external (non-AD) users
Windows authentication for domain users both internally and externally
The ability to enter domain logon details when using iPads (no windows auth)
The core idea in the solution I came up with was that we used Active Directory Group Policy to add a custom string to http request header user agent, the content doesn't matter, in fact we used a long random string of characters.
https://technet.microsoft.com/en-us/library/cc770379.aspx
Then the landing page for the site checks for this, and if found redirects to a virtual directory, with windows auth, that checked their AD account, populated the ASP.NET authentication token and then redirected them to their home page.
If the custom header isn't there then it just displayed the normal login form.
The only other thing was to add an AD email/password check to the normal login form so that if a domain user accessed the site from a non-windows device (iPad) then they could use their normal login details.
Why not put your website code on the server, robocopy it to two separate websites and just handle the changes in authentication by configuring the web.config. (one would be setup with anonymous and one with windows authentication.)
It's not as snazzy as other methods but it's relatively painless. There are two sites but the content (except for the web.config) are identical.
I have an ASP.NET site on a public web server, where users login using forms authentication.
I would like users within certain organisations to be able to login automatically through Windows authentication (bypassing the login page). However, because these clients are on lots of different servers, I can't just build in Windows security to the main site. (I know there are articles on how to mix Windows and Forms security.)
My idea is for each organisation to install a page onto their intranet which redirects to my website and authenticates the user according to their Windows domain and username. Is this possible to achieve securely? How could I go about doing it?
What you have described is almost federated identity.
As well as a page on each site, you will also need a webservice whch will validate a token.
Essentially the flow is:
User comes to your logon page
you redirect them to their company logon page
their company logon page takes their credentials and redirects back to you returning a token
you then call their webservice to validate the token an determine who the user is.
Many public API's use this scheme (facebook being a notable example).
look up oauth and federated identity for more information.
I'm trying to add LDAP support to an existing ASP.NET website that uses Form Authentication. This is not a big problem, I just build a simple login dialog (ordinary HTTP POST), query the LDAP directory and log the user in via Form Authentication ticket.
It would be extremely nice to automatically get the users credentials via NTLM (Integrated Windows Authentication) without the need for a login dialog (like what you get when using ASP.NET Windows Authentication with computers in the same Active Directory). Is there an easy way to do this (keep in mind, I can't use Windows Authentication for my ASP.NET app and the server is not in an Active Directory Domain, I need to be able to query LDAP directory manually)? Or would I have to manually do all the LDAP handshaking / challenge/response thingy?
Thanks for your help,
~ saxx
I do just this on my intranet here. These are the steps I use...
Create a login page (login.aspx seems good) & set the web app up for forms authentication. Set authorisation as deny anonymous. These means any attempt to use your app will cause the user to be redirected to your login page if they don't have a auth ticket.
Now the important step. In IIS, set the app to allow anonymous only. On your login page change this to only be Windows Integrated. Now what happens is when the user is bounced to your login page, IIS forces an NTLM authentication. We now have the users name in the headers.
2nd important step. in the page_load method add:
FormsAuthentication.RedirectFromLoginPage(Request.ServerVariables["Logon_user"], false);
What this does is take the username IIS will always give us and put into a forms auth ticket.
There's of course a certain amount of tidying up you may want to do, perhaps adding a logout feature, or stripping the domain name of the username.
Simon
I'm wanting to secure ELMAH in an internet facing application. The system uses Forms Authentication, but doesn't currently have any non-user accounts (e.g. Admins). The user accounts are set up in an automated fashion.
I don't really want to shoehorn any admin accounts into the system (the current DB schema for the users would be quite inappropriate for storing an admin user in), so I was thinking of corrupting the Forms authentication by checking for an SSL client certificate. If I pick all the right options in IIS, I believe I can ensure that only certificates issued by our internal CA (currently used for non-production sites needing SSL certs) will get passed through to ASP.Net.
I can then use the presence of a Valid ClientCertificate (checking IsPresent and IsValid properties of Request.ClientCertificate) to know that this is a connection from an internal user, and set the Forms Authentication cookie as "Diagnostic" or "Admin" (Or any other special username), and then secure elmah.axd using any of the usual methods suggested for doing it via Forms Authentication.
So my question is - am I overcomplicating things, missing something obvious, opening a massive security hole, etc?
Why don't you just store an admin user account credentials within Web.Config and lock down the URL using Forms Authentication anyway?
Edit
Ok, if the application is entirely internal anyway, why not secure a subdirectory of your site (e.g. myapplication.domain.com/exceptions/elmah.axd or even just myapplication.domain.com/elmah.axd) using Active Directory and set authorisation through IIS?