I am new to web app development.
Basically, I have got a GWT based web app. A user first needs to login. After successfully authenticated himself, he will be taken to the second page (actually another GWT view in the same page).
The login will generate a pair of keys from another web service. These key will be used for future communication with the web service, it is like:
client -> server => web service
Now the problem comes, I cannot save the key pair in a database. What shall I do?
I have been told I can put the key in a cookie and send back to the client. Every time the client raise request the cookie will be sent to the server.
I have also been told to set the keys as the session key and send them to the client.
I am note quite sure what is the different between these two methods. Are they applicable? or secure?
Many thanks
Both methods are applicable. The first one (using cookies) will rely on the user side (its cache). Second one, will keep data on server side (session). As a rule (although it's arguable), you never trust the client. What if client made a clear cache to his browser.
Even for security (I am not an expert here), I think storing data on server is always safer.
You can use both cookie as well as session or a combination of both to achieve this. Cookie are usually created when you launch your application (Also you can create it as and when required). The disadvantage of this is, it is temporary. As soon as you clear the cache or cookies, whatever cookie you created will be removed. If you store it on server side i.e., in session you must make sure to create a separate key value pair for each set of user, as many users can connect to the same server. The best approach will be using both the option together. I.e., to save a cookie and validate the session id.
This link will help you understand how create a cookie and session.
Related
My current system architecture for a web application looks like above. Essentially, its just one code base, that is being deployed in different contexts, so for instance, app1.localhost.com, app2.localhost.com.
These are my current challenges -
I need query my webservices using ajax calls from user browser. But, somehow I need to tell the webservices, that the request is coming from user1 for app1 or user2 or app2. Accordingly, the webservice can go query the right schema in the database and return the results.
My webservices need to be stateless.
I cannot have the user tamper with the request from the browser.
Is this a flawed model? Are my expectations out of standard way of doing this? What is the best way to realize this architecture?
Let's go through this step by step.
So your webservice needs to know the application and the user.
Easy: just include it in the request as a parameter or as part of the url.
Same goes for some information possibly provided by the user.
The challenge comes with the requirement that the user must not be able to change the request.
This is typically achived by cryptographic signing the request (or the sensitive parts). I kind of assume that replay attacks are also an issue.
Create a certificate for the apps.
On the application server create a nonce.
Sign the nonce, the application name and the user name using the certificate.
Include nonce, servername, username and signature in the request used for the ajax call.
Check nonce, servername, username and signature match in the webservice
Check also that the nonce wasn't used before.
Checking the nonce does require some state, but just a list of nonces. If you make the nonces increasing you can even discard any nonces much smaller than the last one you received, limiting the amount of state even more.
You should check if something like this exists as a ready made protocol, because it is always a bad idea to create your own security relevant protocols.
I have two web Applications. I will login in to one Web Application and will navigate to another by links or redirection from the first Application. Lastly after completing some steps in Application two, I will be redirected to Application one. How can I implement this?
Here Application two is generic, and I will have three instances of Application One, which will interact with Application two.
Please suggest a better approach. I have to use spring and Spring Webflow to implement it.
Technically, session between two web application (two different WARs) cannot be shared. This is by design and done for security reasons. I would like to make following comments and suggestions for your problem,
Session are generally tracked using an session ID which is generally stored as a cookie on the browser and Session object on the server side.
This cookie is sent server side every time when you send a request.
A cookie will be sent ONLY to the server where it came from.
So a cookie set by www.mysite.com/app1 will be sent only to www.mysite.com/app1 and not to www.mysite.com/app2.
For you case, for a user sessions to be valid across two application, the browser will need two cookies to be set from app1 and app2.
One way would be, when you login to app1 , using java script, also send a login request to app2. When both these request return successfully, your browser will have session for both the applications (app1 and app2)
Now logout will have its own challenges, when you logout from app1, you also need to logout from app2. Technically this means, you need to clear the cookies set from both of these applications. With little help from java script you can do this.
When you have to make a call to app2 from app1, pass all necessary information via the request object (as a request params) then app2 can read and create the session there (perhaps a servlet/filter can be used for this).
you can share a session between the same application (app1 and app1) across machines using clustering.
I was wondering if there was a "standard" way for handling persitent HTTP sessions in a GAE based web app. Let me explain my issues.
If I only use this.getThreadLocalRequest().getSession() to get a session, this session will be automatically invalidated once the user closes the browser.
If I go with Cookies (so the session will persist until the cookie expires or the user erases his cookies), I need to have a kind of mechanism for validating that the sessionID stored in the cookie actually belongs to a valid session. I've thought about storing a key value pair of sessionID, HttpSession in a concurrentHashMap, but now I run into the problem that this hashmap will be available only for the current instance, therefore I might run into consistency problems.
The last solution I thought of was keeping track of the session in the datastore, but it seems pretty ridiculous to me having to query the datastore each time I receive a request.
Maybe I'm totally out of the track and there's a really simple way to achieve what I'm trying to do: Http sessions that persist across browser restarts and multiple gae instances.
Thanks!
Rodrigo.
You typically use a cookie to implement remember-me. The idea is to generate a random and unique cookie for an authenticated user, store it with the rest of the user information in the database, and send the cookie to the client browser.
Now, when the client comes back 5 days later, the cookie is sent with its first request to your application. At this time, if the user is not authenticated yet, you can extract the cookie from the request, find the user in the database who owns this cookie, and automatically authenticate him as if he sent his credentials.
This solution doesn't need to modify anything to how the sessions are handled by GAE.
Best way managing session in Java. I heard that cookies are not reliable option for this as they gets stored into browser and can be accessed later on? Is this correct? If possible please come up with the answers with the coding example.
Which is the best among:
URL Rewriting: Server will add an additional parameter at the end of URL link
Hidden parameter in Form: server will add an additional parameter at every form in HTML
cookie: Server will ask browser to maintain a cookie.
The session management (client identification, cookie handling, saving session scoped data and so on) is basically already done by the appserver itself. You don't need to worry about it at all. You can just set/get Java objects in the session by HttpSession#setAttribute() and #getAttribute(). Only thing what you really need to take care of is the URL rewriting for the case that the client doesn't support cookies. It will then append a jsessionid identifier to the URL. In the JSP you can use the JSTL's c:url for this. In the Servlet you can use HttpServletResponse#encodeURL() for this. This way the server can identify the client by reading the new request URL.
Your new question shall probably be "But how are cookies related to this? How does the server do it all?". Well, the answer is this: if the server receives a request from a client and the server side code (your code) is trying to get the HttpSession by HttpServletRequest#getSession() while there's no one created yet (first request in a fresh session), the server will create a new one itself. The server will generate a long, unique and hard-to-guess ID (the one which you can get by HttpSession#getId()) and set this ID as a value of the cookie with the name jsessionid. Under the hood the server uses HttpServletResponse#addCookie() for this. Finally the server will store all sessions in some kind of Map with the session ID as key and the HttpSession as value.
According to the HTTP cookie spec the client is required to send the same cookies back in the headers of the subsequent request. Under the hood the server will search for the jsessionid cookie by HttpServletRequest#getCookies() and determine its value. This way the server is able to obtain the associated HttpSession and give it back by every call on HttpServletRequest#getSession().
To the point: the only thing which is stored in the client side is the session ID (in flavor of a cookie) and the HttpSession object (including all of its attributes) is stored in the server side (in Java's memory). You don't need to worry about session management youself and you also don't need to worry about the security.
See also:
Authenticating the username, password by using filters in Java (contacting with database)
How to redirect to Login page when Session is expired in Java web application?
How to implement "Stay Logged In" when user login in to the web application
All Java web frameworks support cookies or URL-encoded session IDs. They will chose the correct approach automatically, so there is nothing you need to do. Just request the session object from your container and it will handle the details.
[EDIT] There are two options: Cookies and a special URL. There are problems with both approaches. For example, if you encode the session in an URL, people can try to pass the session on (by putting the URL into a mail, for example). If you want to understand this, read a couple of articles about security and build app servers. Otherwise: Your Java app server will do the right thing for you. Don't think about it.
The cookie just stores the session ID, this ID is useless once the session has expired.
Servlet specification defines the API for accessing/setting session data in standard J2EE application. Also it defines that session data is stored on the server-side and nothing is transferred to the client except the session identifier. There are 2 mechanisms how session id is transferred:
1) request URL e.g. jessionid=....
2) cookie
Mechanism is determined automatically based on client capabilities.
EDIT. There is no best option, there is servlet specification that defines the way.
Http is a stateless, client-side pull only protocol.
To implement a stateful conversation over it, Java EE Web Server need to hide some information (which is sessionid) in client-side and the mechanism it can use should follow HTTP and HTML spec.
There are three ways to accomplish this goal:
URL Rewriting: Server will add an additional parameter at the end of URL link.
Hidden parameter in Form: server will add an additional parameter at every form in HTML.
cookie: Server will ask browser to maintain a cookie.
Basically, modern web server will have a "filter" to choose which way to use automatically.
So if Server detected that browser already turn off cookie support, it will switch to other ways.
2 important questions:
Which web technology are you using? JSF, Struts, SpringMVC or just plain servlets/JSPs.
Servlets/JSPs already give you the session support you need. JSP Example: Hello, <%= session.getAttribute( "theName" ) %>
I really don't think you have something to worry about cookies, since the data is stored safely in the server and handeling the cookie is done automaticlly.
Is your application installed on a single server?
If YES than you have no problem, use the servlet session option.
if NO than you gotta find another way to do this. Like using a sticky session, or maybe parse the entire session object in the requests/responses as a field. This option indeed requires you to take security measures.
I work on a task that involves moving/traversing from one application to another. The applications are in separate JVMs.
While traversing to the other application, I keep track of the session ID. However, as I traverse back and forth, a new session gets created. Is there any way for me to get back the same session, using the sessionId that I retain, when I navigate back into my parent application from a child application?
Environment: J2EE with WebSphere.
As mentioned by Mork0075, the sessionID is tied to the cookie name and the server domain. If you're using the same server domain for two apps on separate JVMs, I see two options to maintain the session when switching between applications:
The long shot:
1) If you're using a database for session replication purposes, you can use the same database for both applications, and the sessionID will be available for both apps. The one problem I see here is that the objects in the session may not be available on both sides, since the code would be different etc. They'd probably clobber the other side's session objects unless you maintained the code and such on both sides so the objects were available.
The likely possibility:
2) Use different cookie names for the session on one of the two apps. By default, sessions use JSESSIONID as the cookie, and when you switch to the second app, it tries to look up a session based on that cookiename and can't find it. So, it creates a new sessionID and sends it back to the browser, thus causing your sessionID to change and not be available when you switch back to the original app. However, if you change the second app's sessionID to something else (say, JSESSIONID2) your browser would end up with two valid sessionIDs that would each be valid on their correct application. You can change the name via the administration console under the application server's Session Management->Enable cookies page.
I'am not sure if this helps, but in a ONE application scenario, you would submit a sessionID with every reponse, save it in the URL, a cookie or as a hidden field. By submitting a new request to the server, the sessionID is also submitted, to resolve it at server side. In my understand switching from one application to another means, that you have to give the sessionID with the user, across the applications. If you save the sessionID in a cookie, this perhaps is not possible, because the cookie is restricted to a certain server domain. So ensure that the session is still valid and the sessionID is present after returning to the application started.
You shouldn't have to do this manually. Most app servers support Single Sign On (SSO) so that you can log in to one application and have access to all the applications in the same SSO domain. The app server will keep track of session ids and link them to an HTTPSession object specific to the web app.
See http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/topic/com.ibm.websphere.base.doc/info/aes/ae/csec_sso.html