The sun jdks ship with an NTLoginModule that could be used to authentication. It is documented as part of the jaas guide:
which is accessible from the 'API Specifications' section of the JAAS Tutorials:
Does it also work to authenticate NT domain users when JBoss runs on Linux?
No, it does not even ship with the linux versions.
I did quite a few searches without a lot of success.
I am still wondering how to configure the NTLoginModule with JBoss.
Here some of my dilemma:
1) Should I configure the NTLogingModule both on my client (EJB client) and server?
2) Ideally, I'd like to configure it, for sure, on the client: the NTLoginModule picks up the detail of the current logged user and this can very nicely achieve "single sign-on" kind of capbilities (I authenticate once when login to my workstation, no need to login again). But how does this work with the JBoss client login module? To say it differently, how the subject retrived by the NTLoginModule automatically transfered to the JBoss server? Does the Client login module does that automatically and I just need to configure both modules for my clients?
3) Assuming that I manage to send to JBoss the subject created by the NTLoginModule, how should I configure JBoss to verify this subject? Certainly not with the NTLoginModule as it will just grap the identity information of the current user (the user under which JBoss is running). Let's say that I create my own NTLoginModule, the subject created on the client does not contain the user credentials I think. It has this cryptic NTNumericCredential, which I am not sure what it is. So how can I verify (re-authenticate) the user that was authenticated on the client?
4) Am I just fooling myself and the only option is the JBoss client login module to send user/password to the JBoss server and then a modified version of the NTLoginModule so user and password can be provided (which pretty much means writing my own NTLoginModule)?
Last option is that I completely miss-understood JAAS, the NTLoginModule and the JBoss security (which is possible). Do not hesitate to let me know if this is the case, and I will go back reading.
Thanks in advance for any help.
There is no use for the NTLoginModule on the client side other than authenticating that the user is allowed to use the client app. Its the jboss client login module which must be present to propagate the login information to the server. On the server side the NTLoginModule would simply be validating the caller against the configured nt domain.
To do some sort of single sign-on would require some custom server side login module that could meaningfully validate the NTLoginModule result. The jboss client login module is still needed to propagate whatever is needed to the custom server side login module.
Thanks for the reply.
It confirms what I was slowly discovering.
I did more research and it seems that on windows, using the Microsoft Security Support Provider Interface, I could achieve a single sign-on mechanism transparently using NTLM (Windows NT domain) or Kerberos (Windows 2000/2003 domain).
But (of course there is a but), the authentication mechanism involves multiple client/server exchanges (the client and the server are going through a specific dialog before the server can trust the client).
The real question is if JBossSX provides enough extension points to plug such mechanism, especially if it involves multiple client/server exchange before the authentication is really done, which means that both server and client side must be extended.
Actually, it is equivalent as trying to plug the Java GSS-API (the java version of the Microsoft SSPI) as part of the JBossSX client/server authentication process.
As anyone already thought about doing something like that? Does it make sense?
You can take a look at SRPLoginModule as an example of authentication mechanism that involves multiple client/server exchanges. So the answer to your question is Yes, it can be done. The real problem with this kind of implementation (based on RMI) is that it is either not really secure (as is the case with current SRP implementation) or would be inefficient (compared to transport level security) because you would have to add custom interceptors to encrypt/decrypt messages using session key.
Thanks for the answer.
I did not look at the SRPLoginModule before.
One good thing is that it seems that this multiple client/server exchanged can be achieved ?just? by creating special login modules (and a supporting MBean), so it is not ?too? intrusive in the JBossSX framework.
I am a little puzzled by your comment on the ?not really secure?.
Everything that I read so far about protocols than can be plugged behind the GSS-API (like Kerberos) does not assume that the link is encrypted to be secure, at least for the authentication part of the protocol.
It is true that such protocols are also offering message encryption capabilities once the authentication has been done and a session key has been generated.
What I am trying to understand is what the security risks are. Here is my current understanding:
- If I understand correctly something like Kerberos, the authentication process is secure without requiring an encrypted channel. What I mean is that someone can not pretend to be someone else without knowing its credentials, and you cannot determine the client credential by watching the data exchanged on the wire.
- After the authentication process, I agree that without a secure channel, someone can see (and potentially alter) the data being transferred. But this is a different ?issue? and SSL is the answer if you want data privacy on the wire.
- Final possible risk that I see is, since the channel is not secure, someone can see the data being exchanged and manage to impersonate the client (create other messages for the server making it believe that it is the original client). If such risk exists, could we imagine just ?signing? the message instead of completely encrypting it? This should hopefully still be faster than full SSL, shouldn?t it?
My ultimate goal is not necessarily 100% bullet proof authentication mechanism. But GSS-API with Kerberos and the corresponding Login module seems to be able to provide a few nice things:
- Single sign-on capabilities. The credentials of the user running the client process can be ?automatically? used to authenticate against the server without having to re-enter user/password.
- In such single sign-on context the password of the user is not transmitted on the wire (only a ticket is), so it is already more secure than any other solution that do not use an encrypted channel.
- If you want bullet proof security, nothing prevents you to configure SSL between your client and server on top of this authentication mechanism.
RMI protocol is pure stateless. It means that every remote call should contain some additional information about the caller and its credentials, if we would like to support authentication and authorization on the server side. By using this information, the server side security interceptor and server side security manager provide authentication (comparing the income actual caller/credential information with the correspondent information from the internal cache), and authorization (comparing acceptable roles for caller and for remote method, which is being called). In case, the internal cache does not contain the data for actual caller, the server side Login Module is asked for desired information.
So, during the authentication (in common sense) it is necessary to provide caller credentials to Login Module (or place, from which this Login Module will fetch this information).
In order to do it, and avoid transferring the actual password value on the wire, you can use some kind of asymmetric key exchange protocol (SRP for example). It means that your client side login module (complaint to JAAS ) will communicate to some server side component (for example JBoss service, or something else) and perform this work. By the end of this process, both sides will hold a unique session key (this caller private credentials), which are actual only until the caller session is alive. This is similar to login to windows domain, when you get some key, which is actual until you logout, or shut down your host, or something like that. This session key will be transferred by every call from client to server and used for authentication purposes, as I described in the first paragraph.
It does not mean however, that the data, which is transferred on the wire is encrypted. So, somebody could hack/debug the invocation (in theory), extract the session key, end use it maliciously for for sending his own commands to the server. This could continue until this session is not void. In addition, authorization is not bypassed in any case.
Returning to you case:
> I am a little puzzled by your comment on the ?not really secure?.
I think that in this context it means that the RMI call is not encrypted. You can do it by yourself, or use third party ?tool? (which is preferable, I think), like SSL.
> - If I understand correctly something like Kerberos, the authentication process is secure without requiring an encrypted channel. What I mean is that someone can not pretend to be someone else without knowing its credentials, and you cannot determine the client credential by watching the data exchanged on the wire.
Yes. But only during the authentication process. After the end of this process, during the ordinary work it is possible to intercept the ?session key? and use it for you own goals.
> - After the authentication process, I agree that without a secure channel, someone can see (and potentially alter) the data being transferred. But this is a different ?issue? and SSL is the answer if you want data privacy on the wire.
I think yes.
> - Final possible risk that I see is, since the channel is not secure, someone can see the data being exchanged and manage to impersonate the client (create other messages for the server making it believe that it is the original client). If such risk exists, could we imagine just ?signing? the message instead of completely encrypting it? This should hopefully still be faster than full SSL, shouldn't it?
I think it will be faster. But the message is ?signed? in any cases (caller/credentials information is added to every invocation). So, such signing will not prevent impersonating the original client.
> But GSS-API with Kerberos and the corresponding Login module seems to be able to provide a few nice things:
>- Single sign-on capabilities. The credentials of the user running the client process can be ?automatically? used to authenticate against the server without having to re-enter user/password.
I am not sure that I understood this point. I think that SSO capabilities are something from different area. If you are speaking about using windows domain user credentials, I think that the SSO (in your meaning) could be achieved (the client side JAAS login module will use windows domain session key/ticket, the server side login module will validate it against windows domain controller during the first authentication, use this ticket from it's own cache on the further calls authentication). But how GSS-API with Kerberos corresponds to it?
> - In such single sign-on context the password of the user is not transmitted on the wire (only a ticket is), so it is already more secure than any other solution that do not use an encrypted channel.
No, it is not so. It is not more secure then any other solution. There are a lot of other mechanisms based on the similar algorithms (and SRP is an example of it).
> - If you want bullet proof security, nothing prevents you to configure SSL between your client and server on top of this authentication mechanism.
I think yes.
You can use a client/server intceptor pair to encrypt the session key so that it cannot be snooped and used by another user masquerading as the authenticated user.
Thanks for the detailed reply, I appreciate.
I think we are on the same page on most points (which is good for me, I am just a beginner in the security arena).
Two extra comments.
1) From my reading of the Kerberos protocol (which might not be true for SRP, I do not know), the session key is securely exchanged between the client and the server and is used, after the authentication process, to encrypt/decrypt messages (similar to what an SSL handshake is doing). So, if we agree that, after the authentication process, client and server share a private key that could not be compromised (the session key), the "statefulness" of the RMI connection can be established by sending the client principal name and a digital signature of the message (encrypted hash code of the message using the session key). This should guarantee that the message is coming from the right person, shouldn't it?
Agree, this is probably not going to be free to compute the message digital signature, but still cheaper than full SSL.
2) For the single sign-on aspect, I agree that this is dependent of the underlying OS (or almost). At least, I agree that GSS-API is not providing single sign-on capabilities by itself. But Kerberos does (which is what windows is using in W2K domain), I think.
So, a combination of Kerberos JAAS login module (available in JDK1.4) and GSS-API (to be authentication protocol independent) should allow me to implement a single sign-on mechanism on any Kerberos based system (windows and Unix).
For windows, I think we can even go one step further. The microsoft SSPI looks a lot like the GSS-API. One could create his own GSS-API implementation on top of the windows SSPI. It does not bring anything new for W2K domains which are Kerberos based anyway (and the JDK GSS-API provides an implementation for Kerberos), but it will work on Windows NT domain (NTLM instead of Kerberos) since the SSPI supports it.
Current implementation of SRP is not secure in a sence that someone who can observe authentication process can impersonate itself as a valid user. The point that I wanted to make is that implementation of secure protocol on top of RMI is inefficient compared to implementation on a transport level. More over, reasonably good implementations of secure protocols are already available in JDK out of the box. This includes SSL/TLS with Kerberos authentication that works with Microsoft Active Directory. So why reinvent the wheel? All you have to do is make JBoss extract principal information from a transport layer. That, I believe, is much easyer to accomplish than implement GSS-API on top of RMI.
I see your point.
I was actually interested by a "fairly" secure authentication mechanism without having to require SSL.
I have the impression that Kerberos provides that (you can securely authenticate yourself over a non-encrypted channel).
But you are right; it might be too much work compare to just leverage SSL/TLS.
The only drawback with this is that I can probably not support NTLM (windows NT domains or machines that have not joined a domain yet, which, I agree, serves no purposes except, may be, demos).
I am also curious to know why you are suggesting that secure protocol on top of RMI is inefficient compared to implementation on a transport level.
If I simplify the problem a ?little?, encrypting a serialized java object at the RMI level or encrypting the TCP packets at the socket level (SSL) should not make a big difference, should it? Or am I simplifying too much?
There is actually a JSR about RMI security (http://www.jcp.org/en/jsr/detail?id=76). Not sure if it will use GSS or not, although it would make sense to me that they do.