views:

297

answers:

4

My application is a Eclipse Rich Client and I would like to add authentication and authorization features to. My Users and roles are stored in a database and my application also has a web based admin console which lets me manage users and roles. I am leveraging Spring security on this admin console.

So here's my requirement:

I would like my thick client to provide users with a login dialog box. The authentication would need to be performed on the server side (it could be a webservice) and the roles have to flow in to the thick client. I would also like to manage sessions on the server side, somehow.

I really can't think of any easy way to doing this. I know that if I were to use Spring Rich Client, it would integrate pretty well with Spring Security on the server side. But, that is not an option for me at this point.

Please share your thoughts on how to acheive this. Appreciate your help.

A: 

Perhaps this will help you out:

http://prajapatinilesh.wordpress.com/2009/01/14/manually-set-php-session-timeout-php-session/

Notice especially this (for forcing garbage collection):

ini_set(’session.gc_maxlifetime’,30);
ini_set(’session.gc_probability’,1);
ini_set(’session.gc_divisor’,1);

There is also another variable called session.cookie_lifetime which you may have to alter as well.

IIRC, there are at least 2, possibly more, variables that you have to set. I can't remember for the life of me what they were, but I do remember there was more than 1.

Helgi Hrafn Gunnarsson
this doesn't relate to my problem. my serverside right now is Spring (spring security). When a thick client connects to a webserver - I am not really sure how I would handle the security part.
Jay
+2  A: 

Since you're leaning toward web services (it sounds like you are) I'd think about taking the user information from your rich client (I assume user ID and password), using WS-Security to send the encrypted info to a web service, and having the web service do the auth stuff. Also I'd think about the web service returning any info that you want to go back to the rich client about the user (first/last name, etc).

SOA Nerd
@SOA Nerd The question is, if I were to return stuff back from webservice - how do I do it? send an xml back to the thick client? then what? who maintains session? this question is more of a how to question
Jay
@Jay - Any session information should be maintained at the thick client with the server being stateless. When the web service returns it'll have your information in the SOAP/Rest message (XML format). With web service clients I usually have usually used JAXB or Axis2 to help me unmarshall this payload into the Java object I want but this may be overkill for what you are describing. In your case something easy like XPath is probably all you need.
SOA Nerd
@SOA Nerd "Any session information should be maintained at the thick client with the server being stateless" - I beg to differ here. How would you have state information at client? What if I wanted to prevent user from logging in from 2 machines (using the same client). There is no way to control this. There is nothing that gives you stats on who is logged in etc. Also, this is a lot of security code on the client side, which is what I would like to avoid.
Jay
Stateful servers don't scale as well as stateless servers and session management is a pain in the ass (and a source of resource leaks). Keep the state on the client. You've got a thick client - you've paid the price (needs a desktop deployment), so reap some of the benefits, such as easy client storage.
hbunny
+1  A: 

I've a similar requirement I think. In our case:

  • user provides username and password at login
  • check this against a USER table (password not in plain text btw)
  • if valid, we want a session to last, say, 20 minutes; we don't want to check username and password every time the thick client does a retrieve-data or store-data (we could do that, and in fact it wouldn't be the end of the world, but it's an extra DB op that's unnecessary)

In our case we have many privileges to consider, not just a boolean "has or has not got access". What I am thinking of doing is generating a globally unique session token/key (e.g. a java.util.UUID) that the thick client retains in a local ThickClientSession object of some sort.

Every time the thick client initiates an operation, e.g. calls getLatestDataFromServer(), this session key gets passed to the server.

The app server (e.g. a Java webapp running under Tomcat) is essentially stateless, except for the record of this session key. If I log in at 10am, then the app server records the session key as being valid until 10:20am. If I request data at 10:05am, the session key validity extends to 10:25am. The various privilege levels accompanying the session are held in state as well. This could be done via a simple Map collection keyed on the UUID.

As to how to make these calls: I recommend Spring HTTP Invoker. It's great. You don't need a full blown Spring Rich Client infrastructure, it can be very readily integrated into any Java client technology; I'm using Swing to do so for example. This can be combined with SSL for security purposes.

Anyway that's roughly how I plan to tackle it. Hope this is of some use!

Brian
+1  A: 

I developed a similar application recently using the Challenge-Response-authentication. Basically you have three methods in your webservice or on your server

getChallenge(username) : challenge
getSession(username, response) : key
getData(username, action?) : data

getChallenge returns a value (some random value or a timestamp for instance) that the client hashes with his/hers password and sends back to getSession. The server stores the username and the challenge in a map for instance.

In getSession the server calculates the same hash and compares against the response from the client. If correct, a session key is generated, stored, and sent to the client encrypted with the users password. Now every call to getData could encrypt the data with the session key, and since the client is already validated in getSession, s/he doesn't have to "login" again.

The good thing about this is that the password is never sent in plain text, and if someone is listening, since the password is hashed with a random value, the call to getSession will be hard to fake (by replaying a call for instance). Since the key from getSession is sent encrypted with the users password, a perpetrator would have to know the password to decipher it. And last, you only have to validate a user once, since the call to getData would encipher the data with the users session key and then wouldn't have to "care" anymore.

Patrick