how to find first request in jsp - java

I want to find the first request which is coming to jsp. Once a window is closed, again I want to find the first request coming to jsp, but I do not want to restart my server. I am trying this:
String name=session.getAttribute("val");
if(name!=null)
{
//something
}
else
{
//something
}
It is working only for the first request. After that, I have to restart the server again and again.
Moreover, I want to find the time spent on particular jsp.

You are storing the data in Server Session. It has invalidation period (configurable, let's say 10 min for example), so it is cleared only after this period. Closing the window doesn't affect this logic at all.
Handling of window behavior should be done on client side with Javascript. Take a look at window.onload and window.onbeforeunload events.
Time spent on the page can also be captured on client side. In general the logic could be:
When page loaded (onload event) you start the timer.
When page is unloaded (onbeforeunload event) you save timer value to some local storage of sending it to server with ajax call.

This is what you are looking for.
How to end sessions automatically if user closes the browser
Killing session when closing the browser
Try with below options:
web.xml
<session-config>
<session-timeout> 5 </session-timeout>
</session-config>
HttpSession.invalidate()
set the cache-control meta tag in the header to no cache to prevent session reuse.

Related

How to logout automatically after session timeout on server in java web application

I have a small web application with simple requirement that, I have a servlet and few JSP pages in my application.
When ever we give request to sevrlet it starts session on server with session timeout 1minute, then it displays one JSP page.
After session timeout on server I want to automatically display sign out JSP page in the browser how can we achieve this.
To add to Jhash
You have to have a timer javascript function on every jsp of your application (you can keep it in a .js file and include it)
Your session on the server can be about 30 minutes and your javascript timer can be around 2 to 5 minutes because even if a cached html page is shown, it would find out the situation within 2 minutes
Hope you are not relying on this for securing the application. You should still check on serverside that the user session is valid before letting the user use your application (the javascript should be only for convenience)
Edit:
Example of guessing timeout in JS and then navigating the user out:
var lastActiveTimeMs = new Date().getTime(); //This is set to current time on page load
var SESSION_TIMEOUT_MILLIS = 35*60*1000; //35 mins in milliseconds
var CHECK_TIME_MILLIS = 60*1000; //1 mins in milliseconds
setTimeout(fnCheckTimeout, CHECK_TIME_MILLIS); //Check the timeout once in a minute
function fnCheckTimeout(){
var curMs = new Date().getTime();
if( (curMs-lastActiveTimeMs)>SESSION_TIMEOUT_MILLIS ){
window.location.href = 'signout.html';
}
}
//Keep updating lastActiveTime every time you do an Ajax call.
//Because server will keep extending the session for every page load or ajax call from client
For this you need to use javascript in your jsp page.
For example if your session timeout is 2 minutes on server, in JSP page also you need to create a timer with same time using javascript, after javascript timer timeout happens, you just need to refresh the page by using same javascript code. so when you refresh the page session timeout happened already on server so you can check for session on server and if session is expired redirect control to the page you want.

how to send an alert when session expires

i wanted to throw an alert when session expires and when you press ok button in the alert box then it will take you to login page. For this i thought to create a timer and timertask and in the run method of the later class i will check if the session exists or not. So for this i tried to create a class in jsp page but it is showing error. i can create in servlet but all my pages are in jsp and so this idea is not useful.Now i created a sessionlistner and in the session destroyed method i want to link to login page but i have a problem here too.I can not use response method in the sessiondestroyed method.Please tell me are there any other ways
You can use JavaScript like:
var sessionTimeout = "<%= Session.Timeout %>";
function DisplaySessionTimeout()
{
//assigning minutes left to session timeout to Label
document.getElementById("<%= lblSessionTime.ClientID %>").innerText =
sessionTimeout;
sessionTimeout = sessionTimeout - 1;
//if session is not less than 0
if (sessionTimeout >= 0)
//call the function again after 1 minute delay
window.setTimeout("DisplaySessionTimeout()", 60000);
else
{
//show message box
alert("Your current Session is over.");
}
}
For more details visit here
First, you can creates totally client side solution: use setTimout() when page is loaded first time. Use either hard-coded or arrived from server value of timeout. When timer is triggered use document.location = login.html (or something like this) to arrive to login page.
This solution is "fast and dirty."
Better solution should be based on real session expiration. You can create AJAX call that tries from time to time special URL. This URL should return true/false that means that session is expired or not. When session is expired you should redirect the page to login screen. The problem with this solution is that the fact that you request the session state refreshes it. To solve this problem you can either perform the request to different server or (probably) remove session cookie from the polling request, so it will be performed in session different from the main session.
With Tomcat you can create a JS timer that make a simple AJAX call.
If the call return without errors the session is valid, if the call fails you can consider the session expired. On default behavior Tomcat deosn't renew sessions if you don't explicitly call it.
I had the opposit case: link
This problem is already solved by the Java EE Spec. You should consider using web.xml configurations to handle session timeout issues. It has specific tags for handling all of this. Some of the tags are:
<login-config> ... </login-config>
The above tag lets you used FORM based authentication where you can specify your login HTML resource.
<security-constraint> ... </security-constraint>
The above tag lets you specify the URLs you would like to secure. And finally the session timeout tag itself, which allows you to specify the session timeout in millis.
Once you do the above, the container would automatically take the user to the login page when he requests a secure URL.
Here is the web.xml reference.
From a messaging standpoint, there are multiple ways of seeing the problem:
The fact that system is taking the user back to the login page and forcing him to login, is indicator enough for him/her.
You could provide a generic message on the login page itself.
Device some tricky flag based or querystring logic to show the message on the login page.
Came across this link in StackOverflow itself which provides a strategy you can implement in the login page itself. Have not tried this though.
This in my mind is a trivial problem compared to the whole session timeout strategy itself.

Resetting session timeout

I've a web page, where user can extend the session using AJAX call to server. If the application configured session timeout is for 30 minutes, he can extend the session for 5 minutes by pressing a button. When this user submits the pages, I need to reset this session timeout value back to the global session-timeout value.
Is it possible in Java to reset it?
or
Is it possible to read the global session-timeout value which is configured in web.xml?
EDIT:
I'm using the following code to extend the session
request.getSession().setMaxInactiveInterval(300000);
How do the user extend the session. I mean do you give a javascript alert/confirm box regarding it.
Ideally, session should automatically be extended when the user submits a request to the server.
setMaxInactiveInterval() in code and <session-config> in web.xml should do the stuff in normal scenario.
Share the exact situation of your application
EDIT:
Sending a dummy request to a JSP should automatically extend the session as session time out is measured in terms of inactive interval and the dummy request should discard the inactive interval till now.
I solved it by setting the default session as a session variable on execution of an action class, then using it to reset when ever required.
I'm not sure this is the right way to solve this. but it solve my issue, at least for now.
The time out and rest function is here and it will work accordingly to the service response.
Time setting function:
$rootScope.SessionTime =localStorage.getItem('mint');
$rootScope.tickDuration=1000;
$rootScope.myInterval=setInterval(function(){
$rootScope.SessionTime=$rootScope.SessionTime-$rootScope.tickDuration
//console.log("secs:::::"+$rootScope.SessionTime);
if($rootScope.SessionTime<300000 && $rootScope.tickDuration >0){
$('#session').modal('show');
$rootScope.tickDuration =0;
}
},$rootScope.tickDuration);
Time out function:
$scope.myTimeout = function(){
var sessionId=getcokkies.getsessionId();
$http({
url: config.apiUrl + '/user/refreshsession?sessionId='+sessionId,
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $.param({
'userId': parseInt(getcokkies.getUserId()),
})
}).then(function successCallback(response) {
//localStorage.setItem("mint", 600000);
//$rootScope.SessionTime = 600000;
clearInterval($rootScope.myInterval);
localStorage.setItem("mint", 600000);
$rootScope.SessionTime =localStorage.getItem('mint');
// console.log("after++++"+$rootScope.SessionTime);
$rootScope.tickDuration=1000;
}, function errorCallback(response) {});
}

Invalidate a session

I have a jsp servlet based application, with session time out of 30 mins, I want to invalidate the session as soon as a person closes the browser window intentionally or accidentally (OS shutdown/close from tast manager/powerdown)
Can I put a check for that and invalidate the session?
It is not possible to handle this scenario .
There are some browsers which provide this setting as their preference , but you can't handle this programitically.
At max:
You can make a poll from page(may be header) same as gtalk in gmail as soon as connection closes wipe that session out.
Why do you want to do that, you have already configured that in server that ,session should stay idle for 30 mins,after that it will expire in server.
if you want to do that use the following javascript or jquery(better for cross browser) , when the browse close event happens send an ajax request to invalidate session by running following code in jsp
(request.getSession(false).setMaxInactiveInteral(0);)
From javascript
<body onbeforeunload="doAjaxCall();">
(or)
jQuery(window).bind("beforeunload", function(){
// Do ajax request and dont wait for the response.
});
You can implement the server push ajax polling , for example think that session is going to expire in another 2 seconds , send a server side request to client to invalidate the cookie and also in the server you can invalidate the session.
if ( (getcurrentTime() - session.getCreationTime()) > 2000 ) {
}
While the page is rendered , get the maxinactiveinterval and then set the value to the JavaScript variable , then use setInterval function , pass the inactiveinterval value to function , once the timeout happens you can set the cookie to expire.
No I don't believe you can do that as there are no hooks available in the browser to get it to send a disconnect notification (of some sort) when it closes and I don't think there is a server-side mechanism to interrogate recent sessions to test their connection status.
If you are using tomcat 5.0/5.5/6.0 container, the cookie generated by tomcat session manager to track the session (JSESSIONID) is a per-session cookie (browser memory only cookie) instead of a persistent cookie (write to disk). That's because the session manager does (hardcoded) setMaxAge(-1), so that the generated HTTP-response contains:
Set-Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/ and no Expire=date.
So when the browser is closed (all browser windows, or just the window containing the cookie, depending on the variuos browser implementations), the cookie - and the session - are lost. [*]
This has nothing to do with <session-timeout>, which is a setting that tells the tomcat server-side session manager to expire sessions when idle for more time than specified.
[*] they will still be persisted on disk on the server-side, till session-timeout expires, but there wont be a request with a cookie activating them.

How to prevent a user from seeing previous users' info by hitting the "Back" button [duplicate]

This question already has answers here:
Prevent user from seeing previously visited secured page after logout
(7 answers)
Closed 4 years ago.
I am developing a java web app using servlet, in order to prevent user from hitting the back button to see previous users' info, I have the following code :
protected void processRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
{
HttpSession session=request.getSession(true);
response.setContentType("text/html");
response.setHeader("Cache-Control","no-cache,no-store");
response.setDateHeader("Expires",0);
response.setHeader("Pragma","no-cache");
......
// if (!User_Logged_In)
session.invalidate();
}
Besides I also have the following code in the file : web/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
......
<filter>
<filter-name>ResponseHeaderFilter</filter-name>
<filter-class>ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>private,no-cache,no-store</param-value>
</init-param>
<init-param>
<param-name>Pragma</param-name>
<param-value>no-cache</param-value>
</init-param>
<init-param>
<param-name>Expires</param-name>
<param-value>0</param-value>
</init-param>
</filter>
</web-app>
And the ResponseHeaderFilter.java looks like this :
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class ResponseHeaderFilter implements Filter
{
FilterConfig fc;
public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException,ServletException
{
HttpServletResponse response=(HttpServletResponse)res;
for (Enumeration e=fc.getInitParameterNames();e.hasMoreElements();) // Set the provided HTTP response parameters
{
String headerName=(String)e.nextElement();
response.addHeader(headerName,fc.getInitParameter(headerName));
}
chain.doFilter(req,response); // Pass the request/response on
}
public void init(FilterConfig filterConfig)
{
this.fc=filterConfig;
}
public void destroy()
{
this.fc=null;
}
}
So far it's still not working correctly. The back button will bring up a warning window saying the data has expired, it asks if the user wants to repost it. If you choose yes, it will still display the previous pages info. What am I doing wrong? What's the fix ?
Frank
Yes, I am developing a web app for a PC in public place, if user B hits the back button he might see user A's private info.
I was trying to use session id with servlet, but how to do it, any sample code ?
I also tried the following :
<Html>
<Head>...</Head>
<Body onLoad=document.execCommand("ClearAuthenticationCache","false")>
......
<script type="text/javascript">
// Clear current credentials : Requires IE6 SP1 or later
// document.execCommand("ClearAuthenticationCache");
document.execCommand("ClearAuthenticationCache","false");
</script>
......
</Html>
It works for IE but but Firefox.
How will hitting the back button cause the user to see another user's data? What is your use case? Is it designed for a public terminal, where each user submits data and then leaves? In this case, associate each input with a unique session id. Keep track of valid session ids in your server. Once the input is submitted, remove that session id from the valid ids. If it comes up again, then don't display the information.
Your problem is that you're trying to keep the client from seeing what's on his or her own computer. You can't keep them from looking at their browser cache. You can't keep them from disabling JavaScript (and thus your scripting code). You can't keep them from using a browser that doesn't observe that "repost" convention that you mention.
This is not a problem that can be solved with JavaScript or a server-side solution. That part of why "breaking the back button" is frowned upon: it doesn't actually solve anything.
Breaking the back button is a cardinal sin of web development.
but you could try a bit of java script in the onload that refreshed the details according to the currently logged in session.
It sounds like your real problem is that the re-post works. That would probably be because you:
are trusting credentials from the browser rather than the current session, or
are not checking that the current session is allowed access the data represented by a key/identifier value sent from the browser
I recommend that after a user has logged in you never trust a user name submitted by the browser. Ideally use the security services of a framework like Spring Security but in their absence you can rely on HttpServletRequest.getUserPrincipal().
To make sure the current session is allowed access the data you could use an Access Control List mechanism provided by a framework such as Spring Security or include a WHERE OWNER=? clause in your database queries.
I'm not sure if I understand your problem exactly. Are you concerned about Person A logging off, Person B logs in from the same PC and browser instance, and then you want to prevent Person B from seeing whatever A was viewing?
If so, it should be sufficient to check the credentials of the user on every page load. Check that the current user is authorized to view the data being requested.
I'm not sure I understand your problem correctly, but it sounds like you are allowing rePOSTs.
One approach to prevent resubmission is to use tokens. Put a random token in the form and session. On submission check that the submitted token matches the token in the session
if it does, replace the token in the session with a fresh one and process the request
otherwise stop processing the request).
All of the different browsers have different behaviors and quirks when it comes to how history relates to the cache and the various headers available to control it. Firefox 3 works differently from Firefox 2, re-displaying potentially sensitive data when a user clicks the back button in spite of using caching directives to prevent it. The best solution is to use a session cookie that is not persisted and inform the user of the need to close the browser window after logging out. Especially if they are at a public terminal. Painful, I know, but current browser offerings and the HTTP specification do not provide any mechanisms for dealing with browser history. History may be treated differently than caching by a user agent according to the HTTP specification. See 13.13 History Lists as defined in RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 for the problem and rationale.
If you're worried about someone seeing what was in a form in a previous page you could use a hidden form for the "real" post and use one that's just for display for the user. When the user submits the display form, you copy all of the fields to the hidden form, clear the display form, then submit the hidden one.
I agree with everyone else - fiddling with the back button this is a bad way to handle protecting information.
I'm not 100% sure this is a fix to your issue, as I don't fully understand how you would get another user's data using back. However, I know that for the web apps I develop I try to exclusively use Redirect After Post to avoid back button and refresh duplicate form submissions.
I think this is as much a user interface challenge as a coding problem. On top of whatever anti-caching techniques you employ, you need to make it clear to the user that they must hit a big, obvious "Logout" button (or equivalent) when they are done.
if this might help. This works for ASP, use an equivalent solution for other languages.
Jeff Atwood described a way to prevent CSRF and XSRF attacks here.
You could use this technique to solve your "users seeing what they should not see" problem.
I had a similar problem in .Net. I added the following javascript to my logout page:
document.execCommand("ClearAuthenticationCache","false");
now if you press the back button you need to authenticate again.

Categories