benjeeqds

Member
Joined
Oct 2, 2008
Messages
9
Programming Experience
3-5
Hey All,

I’ve written a VB.NET client & server application where the client application calls a function on the server and gets results back.

The application runs in an intranet.

How can the server tell who (as in the NT domain user?) the client is before executing a request WITHOUT prompting the user for their password?

(The users hate entering passwords, and I don’t blame them)

Obviously I can’t allow the client to ‘spoof’ their name (i.e., it can not just say “I am domain\bob”, it has to prove it.)

I have a nasty solution which works (shown below), but surely there is an API or something for this?

I can’t use IIS Windows Authentication, as this is a VB .NET client app talking to a VB .NET server app.

Hopefully somebody can shed some light?

Cheers,
Ben


PS: I have a nasty approach, which follows:


Step 1: Client application creates login request (“hello I want to log in as domain\ben”) and saves into \\server\sso$\request\ben.xml.

Step 2: Server application detects new file (ben.xml) in \\server\request\sso$ directory

Step 3: Server application creates a file called \\server\sso$\response\ben.xml and sets NTFS security permissions on so only "domain\ben" can read the file

Step 4: Server checks permissions on the file are set correctly – if not then it kills itself and refuses accept any connections (This handles cases where the system is running on FAT32 file systems with no permissions).

Step 5: Server saves a magic word (eg ‘abracadabra’) into the file \\server\sso$\response\ben.xml

Step 6: Client application reads the file \\server\sso$\response\ben.xml and gets the magic word ‘abracadabra’ (remember, only ‘domain\ben’ can read this file due to NTFS security set in step 3)

Step 7: Client sends work request via normal TCP connection, and includes work request, user name and the magic word (client says “Attention! Do function xyz with paramaters abc, I am domain\ben, my magic word is ‘abracadabra’)

Step 8: Server does the work and returns results to ‘domain\ben’ via TCP, then kills the connection and banishes the magic word. Next round of communications go back to step 1.

(Obviously my ‘magic word’ is a 256bit long random string, not a silly word)



----------- the solution I crafted above makes me cringe and shudder :) ------------
 
Last edited:
Perhaps take the My.User.Name and send it to server for authentication?
 
If you are using the windows account user, wouldnt they arleady be authenticated to your network?

If you are allowing the app login to be different then the current windows user, how would you want to authenticate it without a password?

I have some coding examples that will authenticate a user with the networks active directory but not sure exactly how you want to prevent anyone from signing on as Ben without a password.
 
Tom - sorry the client app is authenticating as an AD user, when it says "i am domain\ben", it's using the domain and username from AD.

Cheers,
Ben
 
Hey John,

Thanks I've got the username (my.user.name) and I send it to the server, but I can't figure out how to secure it so the server knows that I really am "my.user.name" and not just impersonating somebody else.

The solution I wrote prevents impersonation, but I thought there was a more elegant model?

Cheers,
Ben
 
I don't see how impersonation could be a problem, it is the same as logging in as user with valid password.
 
John,

Users impersonating other users would be a huge problem; imagine if a user was able to change the My.User.Name string from "domain\fred" to "domain\bob" and steal all of Bob's personal data.

That's why I came up with the whole 'magic word' thing, to eliminate this problem.

I'm going to keep researching this today and post back here when I find some answers - surely somebody has come up witha a solution for this before!?


Cheers,
Ben
 
When Fred has Bobs credentials he can log into computer with the Bob account, impersonation is no different. You can't tell which person is actually logging in with a Bob account without doing a fingerprint or eye scan.
 
Hey John,

Thanks for your help - I think I made this way too complex with a poor selection of words.

Basically, all I was trying to do is have a VB.NET application on the client computer ('workstation') talk to a server application and the server application know the name of the user who is logged in on the workstation.

I wanted to do this with out the user having to enter their password AGAIN (because they are already logged into the network / windows, so I though I might be able to find out what useraccount they are running the client application under?)

I found something in IIS that does this with Internet Explorer, called "NTLM Authentication" or "Windows Integrated Authentication". It's awesome, as long as your server is in the Trusted Zones (which I can adjust via Group Policy).

I gave up on VB .NET and have started rewriting the application specifications to be a web-based ASP.NET application so I can simply use "Windows Integrated Authentication" and call the Request.ServerVariables("LOGON_USER") method.


But, the question may still be valid for other people out there - is there a way to do a similar thing in VB .NET?


Cheers for your input!


Ben




PS: What I was talking about Fred getting Bob's credentials is just Fred hacking the TCP/IP message accross the network and substituting "My name is Domain\Fred" with "My name is Domain\Bob".
 
PS: What I was talking about Fred getting Bob's credentials is just Fred hacking the TCP/IP message accross the network and substituting "My name is Domain\Fred" with "My name is Domain\Bob".
Why? He could just run your app with Process.Start(filename, username, password, domain), or log into computer as "Fred" in the first place. Point is what My.User.Name returns is an authenticated windows user. (="Windows Integrated Authentication")
 
Process.Start requires a password (which we don't have, because we're not bothering the user by asking). Also, that would start a process on the local machine, not execute a command on the server.

Simillarly, the request for the value of My.User.Name is being run on the client application, and could be changed before being sent to the server. Eg, Domain\Fred could change My.User.Name to Domain\Ben before sending it to the server.

The server can't assume that the name being provided is legal, which is why I was looking for some sort of challenge / response code.

It's OK, I'll stick with IIS's Windows Integrated Authentication for now.

PS: "Non-networked, firewalled, computer?" GOLD - so many levels of pure FAIL!
 
My personal suggestion would be to implement a simple logging system. When a network user log's-in to your application; simply log to a file or database table the user name that he signed on as, workstation name and IP address along with a timestamp.

After that it's a simple matter of a small query or report to see if Fred from his own computer is loggin on as Bob and fire Fred. :)
 
Last edited:
Hey John / Tom,

Thanks both for your input.

John - it does seem like its being overcomplicated, but this a government dept, they overcomplicate everything!

Basically, to implement a system in production we have to show that measures have been taken to ensure that users can’t ‘spoof’ other users, otherwise Fred could pretend to be Bob and we accidentally fire Bob for doing something that Fred did.

Can you smell a lawsuit looming?!

The reason this problem came up in the first place is because users login to the Windows domain using a smartcard, 4 digit pin & fingerprint – all without the user even knowing their Active Directory password.

So I’ve been stumped to find a solution where VB .NET can securely connect to a remote service without asking for a password – except the solution I came up with in my first post.

Thanks both for all your help, I’ll keep you posted if I find any VB .NET solutions.

(Although the IIS one is working really well for now).

Cheers,
Ben
 
Process.Start requires a password (which we don't have, because we're not bothering the user by asking).
Process.Start was an example of how the user could impersonate much simpler than spoofing Tcp packets... it was not a suggestion to how you should write your windows client application. Faking the Tcp communication is difficult to start with, but you wouldn't sent the account name in clear text over the wire anyway, you would encrypt it. I don't see why you would trust windows security through IIS and not on client workstation, it is the same thing, same security mechanism. Impersonation/login on workstation require the person to know the credentials in order to run your app under various user accounts. If the user knows the credentials for other accounts he would just login as that user and your IIS "integrated security" solution would be none the wiser. What you're saying is that you want to use the Windows security, but you don't trust the Windows security - what gives?
 
I don't understand what the problem is ?

Assuming you running a standard windows application If someone change could change My.User.CurrentPrincipal wouldn't that defeat windows secuirty completely. If you send my.user and do your transmittion securely then you can say that the person that sent that information is who they say they are. otherwise you can't trust any type of windows security.
 
Back
Top