I'm told that it's possible to make a web application that does not require a login. The user logs in to Windows, which authenticates via an Active Directory (LDAP) Lookup. Then, they should be able to go to my webapp and never see a login prompt. These customers have been referring to this as Single Sign On (perhaps incorrectly and part of my confusion).
But, from what I read Single Sign On from the Tomcat docs is:
The Single Sign On Valve is utilized when you wish to give users the ability to sign on to any one of the web applications associated with your virtual host, and then have their identity recognized by all other web applications on the same virtual host.
This is perfectly clear to me. User has to login once and can access every webapp on an instance of tomcat. But, what I need to do is somehow let them login without ever providing any credentials to my tomcat server.
So, in order for this to work I imagine:
- User makes request for some page
- Server sees no session token and then request the client for some credentials.
- The clients browser without any intervention from the user provides some credentials to the server.
- Then, using those credentials provided by the clients browser it does a lookup in an LDAP.
I've seen some examples which use client side certificates... particularly the DoD PKI system which makes some sense to me because in those cases you configure Tomcat to request client side certs, but just logging into windows I don't see how this would work and what information the browser would pass to the server etc. Is this what NTLM is used for?
First of all - and in case other users happen to visit this page - there are only certain authentication methods that allow you to do promptless SSO. These are NTLM and Kerberos. LDAP - on the other hand - will never give you promptless SSO.
NTLM is actually NTLMv1 and NTLMv2. These are very different and NTLMv1 is deprecated because of serious security issues. You should shy away from Java authentication solutions that fail to correctly identify if they support NTLMv1 or NTLMv2 because they only use the word "NTLM" in their documentation. Chances are the developer's of said security solution don't know themselves which is all the more reason to look for the fire escape.
Contrary to traditional belief both NTLMv1 and NTLMv2 are fully documented by Microsoft but you will still find solutions that claim to have 'reverse engineered' the protocol. It is true that this was needed prior to Microsoft documenting the protocols I believe around 2006 or 2007. Anyway NTLMv1 is a no-no. There's nothing wrong with NTLMv2 per-se but Microsoft has been phasing out NTLM (in any form) in all of its products in favour of Kerberos authentication. NTLMv1 is long dead and NTLMv2 is now only used by Microsoft in cases where no Domain Controller is available. Bottom line: NTLM (in any form) is not really the way forward. We should actually salute Microsoft for taking a standards based approach here.
This leaves you with Kerberos. Microsoft has created a protocol for negotiating and transporting authentication information over HTTP. This is known in Microsoft products as "Integrated Windows Authentication" but it has been nailed down as an official standard under the name of SPNEGO. This is what you should be looking for. SPNEGO supports both NTLMv2 and Kerberos as the underlying authentication mechanism but for the above reasons you should be targeting Kerberos rather than NTLMv2.
I've successfully integrated several Tomcat applications (running on Linux/Solaris) with Active Directory using the SPNEGO Project at SourceForge. I've found this to be the simplest approach. This gives you promptless SSO similar to what for example a Sharepoint server does. This is most likely what your users will expect when talking about 'SSO'. Getting the Kerberos configuration right, generating keys and setting up 'dummy' accounts in Active Directory can be a hassle but once you get it right it works like a charm.
The only thing I do not like about the SPNEGO Project at SourceForge is that I do not understand how often it performs the authentication. My nasty suspicion is that it does it for every page view rather than once for each session. Perhaps I'm wrong in this. Anyway: this highlights another thing to consider in SSO solutions: you don't want to implement a solution that 'spams' your identity provider (say Active Directory) with unnecessary requests.
In a Windows Active Directory environment, Single Sign On is used to mean visiting an internal web page carries your Windows login permissions and the web server can act on them. It is something NTLM is used for, but newer implementations use Kerberos instead.
If you open a Sharepoint Server website it knows who you are without needing a login username and password, but this works only for internal websites on the same network, I don't think it makes much sense for it to work on a public website. (I can't tell if you mean "virtual host" as in an Apache vhost or as in an outsourced hosted server).
Here is a Microsoft document describing how Kerberos authentication works to a web server running IIS / ASP.Net: http://msdn.microsoft.com/en-us/library/ff647076.aspx
It looks possible to do with Apache/Tomcat/Java. Here is a PDF describing a UK University implementation of that: http://gfivo.ncl.ac.uk/documents/UsingKerberosticketsfortrueSingleSignOn.pdf and a Codeplex project for it: http://tomcatspnego.codeplex.com/ and Openfire have some documentation to do with generally working with Java/Kerberos here (http://community.igniterealtime.org/docs/DOC-1060 ).
Is sounds like you are describing what Microsoft refers to as Integrated Windows Authentication.
It looks like Tomcat does support Windows Authentication, based on this article.
For starters, you cannot avoid login. If you want to identify users, you have to have them login. Forget NTLM, Kerberos comes to the rescue - it can do everything in a completely transparent manner.
The SingleSignOnValve is not what you are looking for. If you use Tomcat 7, you can use the SpnegoAuthenticator right away but on 6 you have to use this.