Authentication mechansim for java game client / mysql db - java

I need to figure out how to best authenticate users which are connecting from a C++ game client, against a mySQL database on another server, and I plan on writing a java web service to accomplish this.
Security is of primary concern, I need to make sure that the data flowing across the wire is encrypted, so I'll be leveraging SSL (originally I thought about message level encryption using ws-security however I think it's too much overhead).
What I really need to figure out is what kind of authentication mechanism I should provide. These users will be supplying usernames and passwords, and will be issuing a web request to a service.
I haven't decided whether the service should be a traditional SOAP web service or a RESTful one. The whole idea behind rest is to make the server stateless, and since the client will basically be establishing a session with the service, I don't see a point in using REST here.
Having said all that, what I really need to nail down is how exactly to perform the handshake and how to persist the session.
Are there any popular frameworks out there that provide APIs to do this against a mySQL database?
Again the client will offer up a UN / PW to the server, which needs to decrypt them (SSL should take care of that), authenticate them against the account info stored in a mysql DB, and then return some kind of hash or something similar so that the user's session can persist or the user doesn't have to log in anymore to issue additional requests.
Could anyone recommend a framework / some reading material for me to glance over?

Keep things as simple as possible.
HTTP is already stateless, and the idea of a login followed by a continued session is well established (session cookie). Use this paradigm and you won't have any troubles.
You also get the benefit of a very light-weight and open communication protocol and many good libraries for easy serialization / deserialization of common REST payloads like JSON or XML.
REST also means that you can use the same server with other clients quite easily.

I'd take a look at oauth:
http://developers.sun.com/identity/reference/techart/restwebservices.html
A well established pattern is:
1. log in & receive an oauth token
2. store token in db with user's internal id (and any other data such as token expiration time you wish to store).
3. send token to client, client persists token
4. client sends token for all future requests
5. server fetches user info from token
This method should work well with any client language and any backend datastore.

I would recommend to use REST. As authorization framework you can use standard container's jdbc or file realms on JAAS. If login/password pair is successful, store them at client side. After that, you can perform requests with auth credential supplied per request. I used jersey client for this. For [de]serialization from/to XML/json XStream library "do all dat math". Have a nice day.

Related

Sharing REST tokens between servers

I have a requirement for a REST API that has token-based authentication: we will have replicated application servers with a load balancer, since tokens are generated by one server when a user is authenticated, and different requests from the same client can be handled by different servers, is there a generic technique or technology to share those tokens between the different servers?
About technologies, we will be using the Java stack, more specifically Grails.
About the application servers, we might have more than one database. This comment is important because discussing with colleagues, someone suggested to manage the token sharing using the same database from all application servers. I'm looking for a solution that doesn't need a centralized database, that let us scale on the DB side.
When using token based authentication, there's a server that authenticates the user and issues a security token. Authenticating the user can be done in many ways (verifying username/password against a database, verifying a certificate on a smart card etc).
Once the token is issued and signed by the authentication server, no database communication is required to verify the token. Any service that accepts the token will just validate the digital signature of the token.
The client (caller of your service) is responsible to send the token along with the request. So no matter which server behind your load-balancers handles the incoming request, it only needs the public key associated with the signing key to verify whether the request is valid.
Which security protocol to chose depends on the requirements you have. OAuth is used often for internet applications. WS-Federation and SAML-P are used a lot in enterprise environments.
As far as I see JWT (JSON Web Token) is supported in grails - it seems that this is what you're looking for. Basically you need to separate the authentication server as in this image. Authentication verifies the user/pass being sent and issues a token that is easily parseable without any further access to DB. To only thing that needs to be shared is the key that will be used to decode the incoming JWT. See, how it works.

Authentication token storage recommendations

I have a case where non-interactive devices have to push data to a server periodically over HTTP. I am thinking of taking an auth token approach to verify the validity of requests from these devices.
First the device wakes up and initiates a ssl connection and submits its credentials to the server; the server verifies the credentials and generates a SHA based token, based on the credentials + some random input, and sends the token back to the device
This token must be present as a header in each http request that the device sends up. The server will use a servlet filter that looks for this header and filters out messages that don't have it.
There is no sensitive information transferred, I just want to make sure that the device talking to the server is a valid one, and not someone trying to mess around with invalid data. (Wannabe hackers, script kiddies etc..)
The token needs to be stored somewhere where multiple 'nodes' can verify that the request is valid - where do you recommend doing this ?
I can think of 3 approaches
1) Have a separate web service that maintains tokens and does the authentication ( I cringe on the performance overhead of this for each request)
2) Maintain a Set of authenticated token in the Session, and let the servlet container take care of it using the built in clustering support (Not sure if this is the most fool proof way )
3) Use a database to store the tokens and verify it (Considering Redis for this)
Also, I think this approach has a vulnerability of allowing man in the middle attacks, but since the client sends data only for a few minutes I am taking a chance, any better approaches would be welcome.
My opinion:
1) Have a separate web service that maintains tokens and does the authentication
If it's about performance and you have to maintain a lot of devices, I agree that this may become a performance bottleneck.
2) Maintain a Set of authenticated token in the Session, and let the servlet container take care of it using the built in clustering support.
Personal opinion: never rely on sessions in a systems integration scenario. Second, in clustered environments you have to replicate session state between members. Although the container takes care of this it will have impact on performance as well in case of in-memory replication.
3) Use a database to store the tokens and verify it (Considering Redis for this)
If a database is already in place, do it here
Alternative: Use a symmetric hashing approach. After the device authenticated itself return a one time token (digest) each server node can verify independently (based on certain criteria, e.g. a password). "Shared nothing".
BTW: no question, the transport has to be secured (TLS/SSL).
I think that the 1st solution will be the most scalable and flexible.
Try OpenAM with SAML. This is out-of-the-box solution. It has such a filter and can manage repository with such data. A more bulletproof solution could be based on WebSphere DataPower and SAML. If SAML is too complex you can use lightweight, custom solution, but IMHO the 1st idea will be the best.

Authorized Flash Client to Java Server connection

I'm building a Flash-based Facebook game with a Java backend, and I'm planning to use a RESTful approach to connect the two of them (not a persistent socket connection). I'm using the AS3 library to connect the client to Facebook, so that's where I have my session information stored. However, how do I authorize client connections back to the server? I can't leave the callback URLs open since that'd let people manipulate game state without playing the game. I need to make sure that the calls are coming from a valid client and through a valid session.
At the moment, users have no direct login to the backend server -- it's all handled through the client frontend. Can I pass the Facebook OAuth2 access token to the backend in a way that the backend can verify its validity? Should that be enough to trust a valid frontend connection?
I could do a two legged OAuth signed request or just use a simple shared secret, but the keys would have to be packed in with the flash client, which makes that almost useless for this use case.
Somebody has to have solved this problem, but I can't find it.
If you are using Java as a backend, I would consider using BlazeDS. It is a great library for doing AMF connections (which are async so fit your non-persistent socket requirement). If you are using Spring on the backend at all, I'd highly recommend using Spring-Flex as well. It adds a bunch of goodies that make exposing AMF services a breeze. Also, it adds hooks to allow 'easy' integration of Spring Security.
For the oAuth stuff, I would move the oAuth portion to the web side instead of the flash client (which I think I understand is what you do now). This way you can authenticate the web session on the server side and secure the page that contains the .swf. Then when your user loads the .swf in your code (assuming you're using spring security integrated into BlazeDS) you can call cs.authenticated on your cs:mx.messaging.ChannelSet. This will work, but may be more reword than you want to do.
We had similar problem in one of our project. What we ended up doing was used the following token passing method:
1) Fresh client connects to the server and get a token that's valid for x amount of time.
2) The client has an obfuscated part of code that uses an algorithm to change the token (and this algorithm changes at some frequency in sync with the server). The client uses the algorithm to change the token and includes it in the next request to the server.
3) The server knows the original token and the algorithm so now it can check to see if the new token in valid and it's from a valid client.
4) The cycle continues.
This is no 100% secure, since someone can really spend time and analyze the communication and eventually understand the pattern, but you can play around with the algorithm so much and change it often enough to make it hard for someone to guess it.
Hope this helps.
P.S. The application that I'm talking about that uses this has been in production for past 5 years and gets ~300k unique users a day and no one has broken in yet.

Securing a REST API

I am in the middle of developing a PHP social media web application which will be supported by various web services each operating a REST API. Web services will probably be implemented in Java with MySQL data layer but the whole point of what I am trying to do is make it really easy to implement modules in different languages/data stores depending on what is approriate.
So for example when the user logs into the application via a login form the PHP code connects to a web service and POSTs the username and password to check if they should be authenticated. I would normally at this point start a session and store it in a session data store.
Another example could be if a user sends a private message to another user. The message would be POSTed to the private messaging web service which would take care of all the storage. Similarly the web service could be contacted to retrieve messages for a user.
Although I understand how to implement the REST web service in Java and make the connection to it in PHP I am totally unsure as to how to secure the data being passed and make sure that it is the users data being returned. If for example I want to get all of user As private messages how does the web service know to return that users. I could pass that users identifier as part of the GET url but then surely any old user could just figure out the GET url and use it to look up other peoples messages. I thought maybe I could pass over the session identifier and IP address which would allow me to check the session data store and make sure it is the correct user?
To secure the data that is important - like the username/password I thought I would just pass it over SSL.
Hope this explains my problem better.
Thanks
Take a look at HTTP Digest authentication. Most clients should support it, and it means the auth details can be passed securely with each request as part of the headers without interfering with the payload of the request itself.
I think requiring OAuth is a good choice. Your end users should appreciate that other websites don't need to ask usernames and passwords to access their data. As far as SSL, it's clearly worth doing if you can. You'll have to see if the performance trade-off is acceptable.
Keep in mind that your api must mimic the HTTP protocol.
Http is stateless, and by adding any Sessions or so, you're trying to fake an "Alwaysconnected" method.
With a LoginForm, it's like I'll have to send two requests for each calls ;)
These are basically 2 questions.
When privacy is a concern I'd go for the safest option: Serve data over SSL (via HTTPS).
As far as authentication is concerned, there are several possibilities. Basic over SSL is one of them, but a simple login form with a cookie can be another one. (ASP.Net Forms Authentication for example.) This all depends on how you want to implement your authentication mechanism.

Supplying credentials safely to a RESTFUL API

I've created a RESTful server app that sits and services requests at useful URLs such as www.site.com/get/someinfo. It's built in Spring.
However, these accesses are password protected. I'm now building a client app that will connect to this RESTful app and request data via a URL. How can I pass the credentials across? Currently, it just pops up the user/password box to the user, but I want the user to be able to type the username and password into a box on the client app, and have the client app give the credentials to the RESTful app when it requests data. The client is built using Struts.
Cheers
EDIT - I don't think I made the question clear enough. I'm already forcing HTTPS, my question is more, in-code, when I'm requesting data from www.site.com/get/someinfo, how do I pass my credentials alongside making the request?
You more or less have 3 choices:
HTTP Auth
Roll your own protocol, ideally HMAC challenge/response based
OAuth
OAuth is currently susceptible to a variation of a phishing attack, one that is largely undetectable to the target. As such I wouldn't recommend it until the protocol is modified.
OAuth should also be a lesson about how difficult it is to design secure protocols, and so I'm hesitant to reccomend the roll your own route.
That leaves HTTP auth, which is likely best if you can use it.
All that said, almost everything on the internet uses form based authentication, and many don't even bother with https for transport level security, so perhaps simply sending the password text in the clear is "good enough" for your purposes. Even still I'd encourage using https, as that at least reduces the dangers to a man in the middle attack.
If you can add HTTP headers to your requests you can just add the Authorization header:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where you're using basic authentication and the QWxhZGRpbjpvcGVuIHNlc2FtZQ== bit is "username:password" base64 encoded (without the quotes). RFC 2617
Well, https has nothing to do with authentication, it's just transport-level encryption.
if you interact with an HTTP api, be it that it's https or not, and the dialog box pops up, it means its using HTTP authentication, either basic or digest. If your client instantiates an http client to read data from those "services", then you can pass those credentials when you instantiate the object.
If you use client-side script, XmlHttpRequest supports http authentication as well.
So in terms of code, how you pass the credentials to the RESTful services is dependent on the http client you're using (the object you instantiate to retrieve the data). You can simply collect such a username / password yourself from the client, and use it to call the other service.
look at existing solutions. In this case, oauth

Categories