Authentication token storage recommendations - java

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.

Related

What is the most scalable/secure way to handle refresh tokens in a JWT authentication setup?

I am building my own authentication microservice and although I have the main setup in place (generating access tokens etc.), I am a bit lost when it comes to refresh tokens.
I feel there are a lot of different way to handle this.
You can either store them in Redis or in the database.
You can use a whitelist or a blacklist them
Right now, my idea is to add another database table that links a valid refresh token to a user entity. When a user hits the logout endpoint, the refresh token gets destroyed.
I was wondering if this was a good solution and otherwise, if there are other possible solutions to consider. I have seen a number of articles when googling but they stem from anywhere between 2015 and 2019, and they all have different approaches.
The issue with refresh tokens is not so much where or how you store them on the server side, as well if and how you store them on the client side.
It all depends on whether you can trust your client (software using the token) to keep secrets. You only want to issue refresh tokens to a client you can trust to keep these tokens secure. Typically, this means only issue refresh tokens to confidential clients, i.e. web applications that run on a web server. These clients can also have their own (client) credentials to authenticate themselves with when using the refresh token.
For public (non-confidential) clients, like Single Page Applications, some OAuth2 libraries use an hidden IFRAME and a cookie session with the authorization server to issue new access tokens.
So, the answer to your question depends on what kind of clients you will be using.

How to secure Android App that pulls data from OAuth protected resource

My company is building a RESTful API that will return moderately sensitive information (i.e. financial information, but not account numbers). I have control over the RESTful API code/server and also am building the Android app. I've setup the API to use OAuth 2 with authorization code grant flow (with client ID and secret), and I auto-approve users without them having to approve the client since we own both client and provider. We use CAS for SSO and I am using this for the Authorization server as part of the OAuth 2 process when the user logs in to retrieve the token.
I am contemplating various ways to secure the data on the Android app. I've concluded that storing the client id and secret on the device is definitely not going to happen, but am thinking that storing the auth token might work, since it is only risk to the individual user (and really only if they happen to have a rooted phone).
Here are two options I have thought of. They both require me to have a sort of proxy server that is CAS protected, does the dance with the API server, and returns the auth token. This gets rid of the need for storing the client id and secret in the app code.
Here are what I've come up with:
1) Require the user to enter their password to access data each time they startup the App. This is definitely the most foolproof method. If this were done, I'd probably want to save the userID for convenience, but in that case couldn't use the CAS login (since it's web-based). I might be able to use a headless browser on the backend to log the user into CAS and retrieve the token based on what they enter in the Android form, but this seems hacky. Saving the userID is similar to what the Chase app does (if you happen to use this one) - it saves the userID but not your password between sessions.
2) Store the auth token on the Android device. This is a little less secure, but almost foolproof. When the user starts the app for the first time, open the webpage to the CAS login of the proxy server that returns the token (similar to https://developers.google.com/accounts/docs/MobileApps). After the user logs in and the token is returned to the app, encrypt it and store it private to the application. Also, use ProGuard to obfuscate the code, making the encryption algorithm more difficult to reverse engineer. I could also work in a token refresh, but I think this would be more of a false sense of security.
3) Don't use CAS but come up with another way to get an auth token for the service.
Any advice of how others have implemented similar scenarios (if it's been done)?
Thanks.
Well the reason why standards like OAuth are developed is that not everyone has to rethink the same attack vectors again and again. So most often it is your best choice to stick to something already available instead of baking your own thing.
The first problem with clients that are not capable of secretly storing data is that the user's data could be accessed by some attacker. As it is technically not possible to prevent this (code obfuscation won't help you against an expert attacker), the access token in OAuth 2 typically expires after short time and doesn't give an attacker full access (bounded by scope). Certainly you shouldn't store any refresh token on such a device.
The second problem is client impersonation. An attacker could steal your client secret and access your API in his own (maybe malicious) app. The user would still have to login there himself. The OAuth draft there requires the server to do everything it can to prevent this, but it is really hard.
The authorization server MUST authenticate the client whenever possible. If the authorization server cannot authenticate the client due to the client's nature, the authorization server MUST require the registration of any redirection URI used for receiving authorization responses, and SHOULD utilize other means to protect resource owners from such potentially malicious clients. For example, the authorization server can engage the resource owner to assist in identifying the client and its origin.
I think Google are the first to try another approach to authenticate a client on such devices, by checking the signature of the application, but they are not yet ready for prime time. If you want more insight into that approach, see my answer here.
For now, your best bet is to stay on the OAuth way, i.e. having the access token, client ID and client secrect (when using the authorization code grant flow) on the device, and configure your server to do additional checks. If you feel more secure obfuscating these, just do it, but always think of it as if these values were publicly available.

Securing every request of a session by challenge/response?

We need to design a secure web application. I would like to propose a session handling mechanism which does a challenge-response on every request, not only during login using a CRAM method.
The reason is to harden the web application against session hijacking (eg by CSRF) and replay or man-in-the-middle attacks.
Using a nonce is suggested in some places, but in our webapp it seems impractical, as asynchronous requests can go on, or the user could open new windows, hit the back button etc.
Idea: The client and the server have a shared secret (a previously established user password), every subsequent request does again a challenge/response based on that secret, e.g 'response = hash(challenge + hashedPassword)'. The server executes the request only if the response to the challenge matches. Much like during CRAM, but ongoing for every request.
The question: Is this a feasible idea? If so, it surely has been implemented or is even some standard? How would we use this in a java or php based webapp?
The question really comes down to what you want to achieve. If you want to fight CSRF-Attacks, a secret token in addition to the session key is your way to go. However, changing the token in every request will cause problems - not only will the back-button kill the session, but as one webpage usually contains a lot of asynchronously and parallel loaded data (images, css, javascript, etc.), your approach will not enable any additional data to be loaded afterwards, as each additional request will change the required token, thus killing the session.
You may get around this by embedding all resources into the page via BASE64 and other tricks, but that will seriously hinder your possibilities and may have compatibility issues with some browsers.
So, in the end, your approach will not add much security, but will most likely create a whole set of potential problems for your customers. I'd stick to one secret token per session in the URL to fight CSRF and concentrate on securing against other attacks like XSS and user-friendly security measures like two-factor authentication with a smartphone or something similar. After all, the user is the #1 attack vector nowadays.
Update (2012-06-14)
The token will not fight XSS-attacks, but it will defend against basic CSRF-attacks (e.g. by implanting a bogus url call in an image). I've actually had a situation at work today, where I needed to secure a get-request against user modification and worked up some code. The code may be also usable to secure static, session-timeout form- and link-tokens (right your problem).
The idea is to have a server-secret, which is used to generate a hash/AuthToken over data to secure. If a rogue javascript would try to change any of the given data, the AuthToken would not match. In my specific problem, I have one server authenticating a user and have to send his information over to a third party (username, mailaddress, name, etc.). This GET-Request might be easily changed by any user after authentication, so I have to authenticate the GET-Request-Parameters. By rerunning the AuthenticationToken-Process, the third party can compare the resulting AuthTokens, thus validating the incoming data. Without the shared secret, it is (near-to) impossible to forge the data.
On your problem: Having a static token on GET and POST-requests (or a dynamic one like the project of mine) will protect you against simple CSRF-attacks via e.g. links in forums, which a user has to click to get attacked. As the link will never contain the correct token, your webpage is secure. However, if an attacker manages to load a javascript into the webpage via XSS, you're screwed and no technique in the world will help against it, as the javascript can scan the whole DOM-tree of the page to find an capture any tokens whatsoever.
So, it comes down to this:
use tokens on GET and POST-requests to fight CSRF
secure your page against XSS-injections
I find the OWASP cheat sheets are a good resource for such design decisions:
CSRF Prevention Cheat Sheet
XSS Prevention Cheat Sheet
Your scheme sounds similar to the HTTP digest authentication without establishing any kind of session post authentication. Which is probably an improvement over HTTP Basic. And that is assuming both are over TLS!
I am not sure how feasible your scheme might be or how vulnerable to replay attacks or MITM it might be.
If it is an option you might consider the new <keygen> html5 tag which can help establish a two way TLS session. This would be the most secure option..

Authentication, Authorisation & User Tracking without Sessions

Using Java Web applications (JSP/Servlets, no EJBs), what is the best approach for authenticating a user and authorising their actions, without utilising HttpSession's ?
NB The reason for this approach/question is that I wish our applications to remain stateless, so I do not need to replicate full sessions within the geographically dispersed data centers, and can more easily add and remove servers from the cluster.
Thanks
Generate the token after successfull logon and on each request verify only this token. The token, of course, need to be replicated, but it should not exceed 100 bytes of data, so comparing to 'heavy' weight of typical HttpSession, the performance impact would be quite low.
Public Key Infrastructure. Create your own CA, sign and hand out user certificates. Enable client-auth on your sever.
You can use "Hidden form field" or "URL rewriting"

Authentication mechansim for java game client / mysql db

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.

Categories