views:

188

answers:

2

I’m looking for recommendations of how to authenticate user/password combination and verify group association across a number of differing operating systems. Basically I have a C# application that is working in both MS Visual Studio C# and Mono C# and I need to add an authentication mechanism to it to support Windows, Linux, and MacOSX.

For Windows I wrote a quick C# interop to use the Windows only LogonUser APIs. This is working well, but won’t work for systems other than Windows. My ultimate goals is to have the same set of code run on all platforms (Windows, Linux, and MacOSX) with as little OS dependent #ifdefing as possible.

One note – I am trying desperately to use the inherent OS user accounts. I prefer not to maintain my own user account store.

Any thoughts or recommendations on approaches, user authentication techniques, etc are welcome.

+1  A: 

I'm not sure how authentication works on linux and mac but the first thing that comes to my mind is to implement an IAuthenticator interface and have OS specific authenticator classes. You can then switch over to the appropriate class manually via Dependecy Injection or perhaps dynamically on runtime...but somehow your app should be able to identify what OS it is currently running on.

Darnell
Great idea and I’ll defiantly follow that reco. My question was more focused on what mechanisms are available for user authentication across the various operating systems and how have others tackled the problem of authenticating users without necessarily knowing how the base OS is configured for authentication. For example, (I believe) in Windows the LogonUser API will authenticate users locally and over the network in ActiveDirectory but not in LDAP. How would everyone else approach authenticating users across the multiple operating systems and the multiple authentication mechanisms?
A: 

Each system handles local authentication differently. As @Darnell mentioned, you probably would need to write an interface for your authentication, and hide the system specific backend.

If you need to have the same user accounts across multiple systems, ldap for user info, and kerberos for authentication is the only fully supported cross platform way to handle it.

Short of "kerberizing" you application, and insisting that it only run in an equivalent environment, there's no universal method of authentication. Also, LDAP is really the only portable way to query for group information.

A simpler (more portable) option might be to use a pre-shared key of some sort. This way the user would authorize only your program, by giving it a key with which to sign the messages. Checking the message against the user's corresponding key would let you know that a) the user exists locally, and b) the message is coming from a source which the user authorized. You still have the problem of no universal group lookup, but you probably need to do that on your own if you can't rely on ldap.

Note: I still have to stress the following

I would strongly recommend not using someone's password in your messaging, ever, even if this requires you to maintain your own user/password database. You would be circumventing the local security paradigm, and opening up the system to more security risks. This is even more important if the system is using kerberos/ActiveDirectory, where great lengths have been taken to make sure the user's password is never being transmitted over the wire. Using DBMS's as an example - most of them do not tie into the local user database (at least by default), and implement their own user authentication mechanisms. Look at how security works in MySQL, or PostgreSQL.

JimB
I can see your point that if done improperly this would open the system up to larger security risks, however, I don’t see this approach any different than a remote login (VCN, RemoteDesktop, ssh). I would think that either approach (using system authentication vs. application authentication) could have significant security ramifications. [Please note that I don’t disagree with you outright, but am rather trying to spurn more discussion on the topic.] BTW I am encrypting my client/server communications via SSL.
Your approach is like other systems, and I'm not saying that you're incapable of doing it properly, but mistakes do happen (you're using Windows after all ;). Sometimes it has to be done though, and ssh is a great example. The difference there is the exhaustive auditing that has gone into the code. This is still a separate issue from your real question though, and I'll add a new option that just came to mind to my answer.
JimB
Forgot to mention, my worry isn't necessarily the sending of the password in the message (if it's properly encrypted), it's the storing of the password on the sending side (unless I'm not understanding your intention here). If the user is entering their password themselves, then it's less of an issue.
JimB
Yes the user would be entering the username/password as part of the request they are issuing. No storage of the username/password on the client side and the server just uses it for verification purposes (ensure the user can access the data they requested). What I'm really looking for is a good discussion on user authentication schemes and mechanisms and how they relate to differing OSs.