views:

341

answers:

4

and here comes the situation...

A customer has installed my super dooper winforms application. The username and password are authenticated on the app startup with my MSSQL server.

I would like to redirect the user in my webpage and have him as "logged-in" when he clicks the "Update subscription" button within my app (without the need of forcing him to enter the username & password in the webpage).

Any ideas or cons whould be welcome

A: 

Are you storing the users' session? That's how you keep the user logged in until the session expires (timeout, user logs out, etc.).

I'm assuming the user logs into the application, then updates their subscription. Please let me know if this is not the case.

AlbertoPL
Yeap! The user logs into the application and he sould be able to update their subscription. Currently i am not using any session on client side, just a username password check with Mssql records
Chocol8
You need to be storing the session on the server and checking the session to see if they are still logged in. Then bypass authentication if that is true.
AlbertoPL
A: 

I would do it like this: The user clicks on "Update subscription" button in your app. Then your app gets from your server a random string (a GUID or something similar). Then your app opens a web browser with address www.yourserver.com?token=, where token is that string the app got from the server. You use that token to identify and authorize the user. For security reasons this token should be valid for a limited time, different every time user clicks on the button.

Disclaimer: I'm not a security expert and this method may contain glaring security holes. Use at your own risk.

Juozas Kontvainis
+1  A: 

If you're opening a browser for the user, and the page will be requested over HTTPS, then the easiest way would be to add a Basic Authorization header to the initial request, and have your page go off of that.

In C#, the code to pull out the name/password would be like so:

        string authHeader = application.Request.Headers["Authorization"];
        if (authHeader.ToUpper().Contains("BASIC"))
        {
            //get the user's name/password
            string decodedResponseString = Encoding.Default.GetString(Convert.FromBase64String(authHeader.Substring(6)));
            int dividerIndex = decodedResponseString.IndexOf(':');
            userName = decodedResponseString.Substring(0, dividerIndex);
            password = decodedResponseString.Substring(dividerIndex + 1);

Creating the header in the desktop application would be the above, but reversed (i.e. addheader('authorization', 'basic (username:password encrypted in base 64)').

Using the header like so would be the standard way to do this, but in reality you could probably just make your own header (or cookie) with a custom login algorithm information

edit: Actually this might not work; I'm not sure if you'd have enough control over the browser to alter the headers when requesting a page

John
A: 

I would suggest a slight change in your architecture.

Instead of authenticating directly with the database from the WinForms app, create a simple web service that allows you to pass in a username and password and receive an authentication token in response upon successful login. Perhaps make this some kind of hash of the username+password.

Putting the logic for this in your website means the token generation/authentication is all contained within your website code, and you can change it in one place rather than having to ensure the WinForms part and the website part are in sync.

Anyway, the WinForms app can then hold the token in memory, and pass it back into the web site in the query string (http://www.example.com/?token=08A78B2101EB4a09B2ACE8AF6D6BA993). You can then look up the user using the hash, and log them in that way:

select user_id from users where md5(concat(username, password)) = 'TOKEN_HERE'

Alternatively you could generate the hash uniquely on each authentication via the web service (maybe use a GUID), and store it in a table somewhere to map it back to the user ID, with a timestamp to allow you to expire it after a certain amount of time.

Jon Grant