Difference between creating a session and a cookie? - java

I'm working on my first website with the Play! framework, and at one point I'm calling this method when the user logs in:
static void connect(User user){
session.put("userid", user.id);
}
Simply storing the userid in a session, and I can check if it's set on each request, works fine. Problem is, once the browser is closed the cookie is lost, and the user needs to login again. I want to create a "remember me" option, and it seems that the only way to do that is create a cookie and send it with the respons, like this:
response.setCookie("user", userdata, "14d");
So I'm wondering, what's the point in creating a session, when it does the exact same thing? (But does not give me any control over the cookie time). And another thing I havn't found yet, is how to read the cookie from the request?
(And I'm aware of the fact that cookies created with setCookie are not encrypted and I need to call Crypto.sign())

1) A Session in Play! is always maintained via cookie (i.e in client side), this is attributed to 'Share nothing' approach.
2) If you use Secure module (or you can take a look at the code and follow if you are writing your own), the 'authenticate()' method takes the parameter 'remember' and set the session for 30 days (response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d");)
ie. if user doesn't choose to be 'remembered', their session last only until the browser is closed.
3) The real difference is, as you mentioned, session.put() doesn't allow to set session time out. If you want to extend the session then set it on the cookie.
4) If you want additional authentication while user performing CRUD, (even if user choose to be 'remembered' or their session got extended explicitly by you) its better to set the username/id to cache (rather than setting another identifier to session again) and clear it off when user logout. This will scale well if you choose to use a distributed cache like memcache.
5) To read from cookie, request.cookies.get("name") comes handy.

There are two ways to store state in web apps - client side and server side.
On Server-side either you can use Session or Application objects.
On Client-side you can use View State, Cookies, hidden fields, etc.
Session has a timeout duration after which it expires. When ever you access a web application a session is created for you which lasts for a duration. Hence it is per user thing. Even if you increase the timeout duration, it still expires if you close the browser. Application object is shared between all users.
Cookies are a better way to store such information which needs to be remembered for a longer duration e.g. a day or more. You would have noticed that google allows you to stay logged in for days. That is because they use cookies for state management and not sessions.

You should store the user id in cookie in exactly the same point where you did with session attribute. Use HttpServletRequest.getCookies() for reading cookie. This method returns array of cookies, so you have to iterate over the array to identify relevant cookie.
To change cookie, just override it.

The session lets you tie server-side data to the specific browser session: under the hood a cookie is automatically created that the server uses to look up the server-side data associated with a specific browser.
Control over the session cookie expiry is typically done somewhere in your framework's configuration (or sometimes in the web.xml file used by the app server). You can read the cookie from the HttpServletRequest's getCookies method.
EDIT: this is the getCookies documentation, and for the Play! framework see http://groups.google.com/group/play-framework/msg/6e40b07ff9b49a8a for an example of persistent login and cookie retrieval.

Basically a session is only viable for the period of time in which a user is interacting with your application + the session timeout that you specify. The usability of cookies is to store relevant information to the user so that, when they come back to the website again, you may identify them once more.
For instance, if you have both sensitive and insensitive information regarding a user, you could make your application more friendly by determining who they are via a cookie and loading all of the insensitive information. Once they authenticate themselves then you can load the sensitive information as well.
MSDN has some great reference material as to how to work with cookies at http://msdn.microsoft.com/en-us/library/ms178194.aspx

Related

Spring: How do I dynamically set maximum amount of concurrent sessions

Let's say I have app with several account types and each type has its own allowed maximum of concurrent sessions. For example, if the maximum is 1 then when user tries to log in from his laptop while being logged in on his desktop PC he should get an error.
How can I achive that with Spring? I know about concurrency-control but as far as I know it allows to "statically" set the limit for entire context.
I was thinking about SpEL but didn't came up with anything.
P.S.
Also I would like to know is there a specific exception being thrown when user exceeds the limit so I could handle it and show page with explanation why he can't log in.
UPD
Thanks to #Nándor for clever thoughts: when user tries to log in on another device he should be asked to either logout on the current device or on the other.
UPD2
I found that there is a bean of class SessionRegistry and it holds all the neccessery information, also it allows to manually expire sessions. Also I can control amount of sessions with it.
But there's still problem remaining: how do I notify another device that session has been shut down? When I manually expire the session with SessionInformation.expireNow() it give me a page with following text on it:
This session has been expired (possibly due to multiple concurrent logins being attempted as the same user).
The text means exactly what I want but I'd like to handle this as I want. I tried #ExceptionHandler on java.lang.Exception but it hasn't catched anything.
Thanks in advance!
Thanks #Nándor for thoughts, I finally found a solution.
As to managing number of active sessions:
I use SessionRegistry bean, it can manage active sessions on all principals. Also, I think it's worth mentioning that SessionRegistry appears to be empty until I took off the security configuration from servlet config to applicationContext.xml. Spring logs that it successfully put session id to the registry but its still empty unless it's declared in the applicationContext.xml.
As to handle session expiring:
concurrency-control tag has expire-url tag that holds url to which user will be redirected in case of expired session. I can map controller to it and do what I want.

Limit Sessions Per Authorized User in web application

I'm writing the login modules for a JBoss 7.11 web application that needs to limit the number of active sessions a user may be logged into at a time (the actual number will be configurable).
My current plan is to write a custom Login-Module that accepts a user Principal, references the database to see how many sessions are actually allowed per user, and reject or allow depending on whether or not the user sessions associated with that Principal exceeds the limit.
My question is: what the best way is to find out how to reference the number of active sessions that are associated with a Principal?
I do have the obvious option of tracking active sessions in my database and get my count from there, but I'd prefer not to have to use the database for that.
I also noticed an answer (Get HttpSession/Request in a JAAS Login Module) that indicated that HTTPServletRequests can be grabbed, in which case I can get the Session and even the ServletContexts, but I am unsure if there is anything I can do with these to accomplish what I want to do in a Login-Module once I have them.

User Authentication and User Accounts - Basic Programming Techniques

I think the answer to my question is so simple that there's not even an answer to my question lol:
How does the concept of User Authentication/User Accounts work? How does a certain webpage, for example, know to pull up your information and not someone else's when one logs in? Is it really just a bunch of select statetments with a where clause on the userid to pull back info?
When you connect to a website, a session cookie is placed in your browser. This uniquely identifies you so that the website knows from request to request, page to page, that you are the same person. Somewhere on the server, the ID in this session cookie is stored. The server knows you are there. The server knows when you click on a link that you're the same person who generated the page on which the link was present.
When you log in, the programmer authenticates your username and password against the database (or whatever he uses for user authentication), and then stores some sort of User ID on the server, attached to your session ID from your cookie. Now, whenever you request a page, the programmer checks to see if there's a User ID associated with your session ID on the server, and then knows that you're already logged in. It's common at this point, the first thing when you log in, for there to be a bunch of select statements to load your user inforamtion, any new messages, etc. This way, it can display at the top of the page.
For example, on StackOverflow, this would be your name, reputation, amount of badges, and if you have a new message.
The website never gets confused, because the cookies are never duplicated. Whenever someone comes to the website without a cookie, a new value is generated and sent to the user in the response. Then, every request after that, the browser sends the cookie value back with it. There's no way to possibly know (and it would be nearly impossible to guess) any other user's cookie ID, assuming the server wasn't also using IP address to validate session cookies. Regardless, for the programmers, this all takes place "behind the scenes". Programmers just typically access some sort of session data repository where they can store and retrieve information that is valid across page loads. As long as the user doesn't clear his cache or restart his browser, the session data will be available and unique to that user.
It depends on the underlying technology used to create the website. Usually there's a cookie stored in your browser once you log in that uniquely identifies you. Then when you load a page, the site checks the value of the cookie to see how you are and loads information appropriate to you from a database.
As an example, when you log in to Facebook it creates a cookie on your computer. Then when you go to your homepage it knows who you are based on that cookie and uses it to load your profile picture, your friends, your apps, etc.
No switch statements, though. :O
When ever we log in to our accounts, a session or cookie is created by the server. This session or cookie contains all the relevant information that the server needs to identify the user. Once server access this info, it knows which user it is dealing with and hence retrieves the users details only.

Getting the time in seconds in which the session will expire

I am building a web application that has a top thin frame which should show the time in seconds in which the servlet session will timeout.
The problem is that a AJAX call to a servlet which returns the last access time, and the inactiveInterval itself updates the session.
So is there a way I can get information about the session via a servlet that does not incrementing the lastAccessedTime?
Thanks
It seems that no one really answered the question as asked. The last response is closest - and probably best - piggy back the information needed on another request. I would add that if you can count on XHR activity that you can set a response header with the value(s) you want.
Assuming you really want want you asked for - to summarize / restate - a servlet that participates in the session but doesn't update the last accessed time, you should be able to accomplish that with a Filter that chains an overriden HttpServletResponse that returns an overridden Session object - overriding the getLastAccessedTime() method with its own (stored as an attribute in the real session of course). It will probably need to perform its own manual invalidation of the real session.
Questions like this show the age of the Servlet specification, even in its latest forms, there isn't enough control of some of the low-level authentication mechanisms, and overriding can be difficult even with Filters. These limitations manifest themselves using technologies like AJAX.
In thesis, you should not relay the session expiry time on the session time itself, in your case a counter should be implemented by decreasing the login time from the current time.
RemainingTime = CurrentTime - LoginTime
Your ajax call should query this variable.
Hope that solves your problem.
Can I ask for some more details?
What is the real requirement? Is it that the session time out within x seconds of a user logging in?
In that case, you you can use the getCreationTime() method on the HTTPSession object
http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpSession.html#getCreationTime%28%29
remainingTimeInMilliseconds = System.currentTimeMillis - session.getCreationTime()
OR
Is the requirement for the session to time out after x seconds of inactivity? If so then do a
remainingTimeInMilliseconds = System.currentTimeMillis - session.getLastAccessedTime()
There's no need for your top frame to ask the server for the last access time. Why not let every HTML page contain a JavaScript snippet, which sets a defined variable to either last access, or perhaps more convenient, set the variable to the assumed expiration date of the HTTP session. Depending on how you generate your web pages, you can add the code snippet to a default template, or perhaps even add a Filter, which will embed the required code on every HTML page.
Be aware though, that IMHO, the servlet specification only states, that the server may invalidate the session at some point after the expiration time has passed, so accessing the session after the expiration time is not guaranteed to fail.

How do I keep a user logged into my site for months?

I'm using OpenID. How do I make it so that the user stays logged in for a long time even after closing the browser window?
How do I store and get access to the user's User object?
Basically, I guess I just don't really understand how sessions work in Java.
So you actually want like a "Remember me on this computer" option? This is actually unrelated to OpenID part. Here's a language-agnostic way how you can do it:
First create a DB table with at least cookie_id and user_id columns. If necessary also add a cookie_ttl and ip_lock. The column names speaks for itself I guess.
On first-time login (if necessary only with the "Remember me" option checked), generate a long, unique, hard-to-guess key (which is in no way related to the user) which represents the cookie_id and store this in the DB along with the user_id. Store the cookie_id as cookie value of a cookie with known cookie name, e.g. remember. Give the cookie a long lifetime, e.g. one year.
On every request, check if the user is logged in. If not, then check the cookie value cookie_id associated with the cookie name remember. If it is there and it is valid according the DB, then automagically login the user associated with the user_id and postpone the cookie age again and if any, also the cookie_ttl in DB.
In Java/JSP/Servlet terms, make use of HttpServletResponse#addCookie() to add a cookie and HttpServletRequest#getCookies() to get cookies. You can do all the first-time checking in a Filter which listens on the desired recources, e.g. /* or maybe a bit more restricted.
With regard to sessions, you don't need it here. It has a shorter lifetime than you need. Only use it to put the logged-in user or the "found" user when it has a valid remember cookie. This way the Filter can just check its presence in the session and then don't need to check the cookies everytime.
It's after all fairly straight forward. Good luck.
See also:
How to implement "Stay Logged In" when user login in to the web application
How do servlets work? Instantiation, sessions, shared variables and multithreading
Well, the original reason I chose OpenID was so someone else could handle as much of the implementation and security of authentication for me.
After looking into OpenID more, it appears there is something called an "Immediate Request" (http://openid.net/specs/openid-authentication-2_0.html#anchor28).
When requesting authentication, the Relying Party MAY request that the OP not interact with the end user. In this case the OP MUST respond immediately with either an assertion that authentication is successful, or a response indicating that the request cannot be completed without further user interaction.
Because of this I think I could just store the user's openID url in the cookie, and use an immediate request to see if the user is authenticated or not. This way I don't have to do anything with my database, or implement any logic for preventing session hijacking of the long-lived cookie.
This method of doing it seems to be the way OpenID suggests to do it with their Relying Party Best Practices document.

Categories

Resources