I'm working on some old Java code with broken authentication. The web application starts with a jsp file that successfully creates and authenticates a user object. Then a session variable is created with the following code.
session.setAttribute("guiUser", userIdentity);
If I decide to get this user object within the same jsp file:
UserIdentity foo = (UserIdentity) session.getAttribute("guiUser");
System.out.println(foo.getName());
I can succesfully retrieve the authenticated user object.
However, the page is then redirected to another jsp within a different project in my workspace using
response.sendRedirect(targetPage);
When I get to this new jsp page, a login check jsp is run before anything else. The login check has the following code to instantiate a user object from the session variable(or at least this is what I think it's supposed to do.)
<jsp:useBean id="guiUser" class="com.ussposco.sso.UserIdentity" scope="session"/>
<% (code that uses guiUser object) %>
This code doesn't seem to work, because the user object is null. So I tried grabbing the user object from the session with this code.
UserIdentity foo = (UserIdentity) session.getAttribute("guiUser");
System.out.println(foo.getName());
And the object is still null.
I'm pretty new to Java web applications, but I think that this is a problem with the way that the response is redirected. I can see two different cookies in Chrome when I think there should only be one. Also, on the production website, it changes the value of a different cookie than the code I'm using(obviously out of date) uses.
As you are redirecting to the different application you will not get the same session object. Something as Single Sing On (SSO) is required for this.
Related
While upgrading some legacy code from Wicket 1.5 to Wicket 9, I found that redirection to a "Session expired" notification page seems to be partially broken.
I have the following statement, which always used to work before, in the main application file:
getApplicationSettings().setPageExpiredErrorPage(MyErrorPage.class);
Here is the scenario which should trigger redirection to "MyErrorPage":
The user successfully logs in and goes into any menu option.
They sit around for a while, doing nothing, and their session times out.
After this period of inactivity, they click on a link or attempt to submit a form.
At this point, they ought to be redirected to "MyErrorPage".
The menu option invoked in point (1) - lets call it MyMenuPage - could have been invoked with two possible types of syntax:
Either:
setResponsePage(MyMenuPage.class);
Or:
setResponsePage(new MyMenuPage(params));
It seems that the user will only be redirected to my custom error page if the original menu page was invoked with the SECOND syntax.
If the original page was invoked with the FIRST syntax, the user is sent straight to the login page, without any explanation about the fact that their page has expired.
Please can someone advise me how to get the same result in both types of page - which are not stateless, because the user has logged in.
There is a difference between page being expired and http session expiration.
As PageExpiredException's javadoc [I] explains there are three possible reasons for it:
the page have never been stored there, e.g. an error occurred during the storing process
the http session has expired and thus all pages related to this session are erased too
the page instance has been erased because the store size is exceeded
Wicket stores all stateful pages on the disk. Later when you use such page, e.g. by clicking a link, Wicket loads the page instance, executes the click, and render the response.
If the http session is expired then most probably your authentication strategy kicks in and redirects to the login page without even trying to load the old page. If you use Component#continueToOriginalDestination() after successful login then the user will be navigated to a new instance of the old page.
To summarize:
if the http session expires then your application redirect to the LoginPage
if a page instance is expired then by default Wicket will create a new instance of it (see PageSettings#setRecreateBookmarkablePagesAfterExpiry(boolean)) or show the configured getApplicationSettings().setPageExpiredErrorPage(MyPage.class); will be rendered
To debug what happens in your case put some breakpoints at the following places:
https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-core/src/main/java/org/apache/wicket/Component.java#L1061
https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-auth-roles/src/main/java/org/apache/wicket/authroles/authentication/AuthenticatedWebApplication.java#L134
I. https://github.com/apache/wicket/blob/master/wicket-core/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java#L31
Seems like I just have to work round this by always using the following syntax:
setResponsePage(new MyPage());
This is not the end of the world, because at least I don't have to pass any parameters in, in order to trigger the required "Go to session expired page" behaviour.
I have a java web application. I implemented a login system, with user rights a while ago, and included a "remember-me" functionality with unique string ID's saved client side in cookies.
This has worked ok, except for the fact that the remember me functionality always fails on first page load whenever a new session starts. However, since most users access a non-restricted page first, complaints has been absent. Nonetheless, I'd like to fix it. Here is what I have learned.
I use implementations of javax.servlet.Filter to check if a user has rights to se a page. for example baseURL/pages/admin/*. Filter interface has a method called doFilter, which accepts a ServletRequest, and ServletResponse object as parameters. I cast these to HttpServletRequest and HttpServletResponse. The HttpServletRequest gives me access to cookies and session.
If i iterate through the cookies, I find my "remember"-cookie, with the unique ID as a value. However, this ID is wrong.
Now, in my Servlet class, which follows the front controller pattern, I also have a check for user logged in, and remember me. But because this is executed after the filter, it is not sufficient to check only here. Still, I do want to check for every page, even if it is not restricted, as it changes the layout slightly if you are logged in.
The java HttpServlet service method accepts a HttpServletRequest and HttpServletResponse object. In other words, no need for casting here. Funny thing is though, If i try to access my cookies from here, it will give me an identical id for the session cookie, but a completely different uid for my "remember"-cookie.
I have found that my system adds new remember cookies for each of my filters. And if I try to access a page in the admin path, both cookies from /webapp/pages, and cookie from /webapp/pages/admin will be present in chrome inspector. When accessing the cookies in the filter, the /webapp/pages/admin is the only one that will exist. Oppositely, the /webapp/pages is the only one that will exist in the front controller servlet service method.
I guess this is because of the mapping of said filter and servlet, which matches the path of the cookie. The problem is that I never intended there to be cookies stored hierarchically, and only want the one to be stored, at /webapp/pages. My system has now stored plenty of these deeper pathed cookies all over my client network, and whenever a user logs in and out, they might get out of sync with a new uid.
Is there a way I can force retrieving the /webapp/pages cookie over the /webapp/pages/admin cookie? Or is there a way to retrieve both? I could just check both uid's for a match if I can manage that (hence the title of my question)
For the future, I have made sure to set the path of cookie storage, so that the same path will be used, but as the cookies has a year to expire, this will not solve my problems for a long time, unless I find a way to check the correct cookie.
The answer to the title question is; you can't.
The browser will decide which cookies it deems most relevant, and there is nothing you can do to change that. When your filter is mapped to a subpath, and servlet is mapped to a higher path, you will get the best matching cookie for each path.
The specific problem in the question text is caused by a bad coding pattern. The remember me cookies should be stored at a specific path when created, in this case /webapp/pages. This will prevent the cookie from being created as multiples, in hierarchical paths.
There is still the problem of already existing cookies client side. These can be handled by adding the following javascript in a central area of your code, somewhere where you'd know that all users will encounter it:
document.cookie = 'remember=; path=/webapp/pages/user; expires=' + new Date(0).toUTCString();
document.cookie = 'remember=; path=/webapp/pages/admin; expires=' + new Date(0).toUTCString();
This will set the unwanted cookies to expire at an already past date, effectively deleting it.
Now only one cookie with name "remember" will exist for the domain, and both servlet and filters will fetch the same cookie, regardless of their mapped subpaths.
I have a legacy Java 1.6 running localhost with Tomcat 7 application using JSP pages, a frameset with frames, javascript, but no framework like Struts. I pass an object to display in the page from the servlet using the request or session and that works fine.
However, I made some changes recently and now I can't retrieve that same object back from the session or request. It had been working fine previously, so I'm not sure what is broken, but I can't even send a string value back from the JSP's back to the servlet.
I created a new stripped down JSP and I can't get anything back from that either using the request or session. It does the same thing when I push the code our Tomcat 6 web server. Using the debugger, I see the objects populated in the session, but then lost later when a new session is created each time as in using this simple code to get the sessionid:
System.out.println("The session id is: " + session.getId());
The session id is: EB431C19B41957B2BB2EFC3DBAF32241
The session id is: C9CBD30E84D5C93DF6114C1412AE5523
I then see this in firebug under the Header, response headers:
Set-Cookie JSESSIONID=C9CBD30E84D5C93DF6114C1412AE5523; Path=/Name omitted here/; HttpOnly,
so I know cookies are set. I also removed jquery and I"m stripping down the jsp code as much as possible, but that doesn't seem to be the issue.
I'm using:
HttpSession session = request.getSession(true); but using false didn't matter.
session.setAttribute("ObjNameList", objNameList);
The context.xml has cookies set to true and we do use response.sendRedirect, but only if an error is thrown as in: response.sendRedirect("Error.jsp"); There is no place in the code with session invalidate either.
All I'm doing from the jsp is sending a form back using something like:
document.formName.submit(); which works fine. Using this code to try and set a simple string in the session doesn't work either:
session.setAttribute("somevalue","someValue");
Gives me null in the servlet here:
String val = (String) session.getAttribute("somevalue");
Any ideas as to what could be causing this?
Resultion:
It turned out to be an issue with the url, a typo actually, as BalusC mentioned, so the path for the session cookies didn't match between the jsp and the servlet.
Doublecheck if the request URL to that servlet matches the session cookie domain and path. If it doesn't match, then the browser simply won't send the session cookie back along with the request and the server will think that there's no means of an established session and will therefore simply create a new one.
You can check cookies in the HTTP traffic monitor of browser's web developer toolset (press F12 in Chrome/Firefox23+/IE9+ and open "Network" tab). When a new session starts, the server must have returned a response with Set-Cookie header with therein the cookie value and path (and implicitly domain). When the browser sends a subsequent request on the same domain and path, then it must have passed that cookie back via Cookie request header.
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
I am new with Selenium Webdriver and trying to create my first test cases for application that is constructed mostly with PHP. I am creating test cases with Java.
My first test case is testing login into the system. When I run my test, browser instance is started, login information is set into login form fields and login form is submitted. After that browser dericets to used users start page as it should. So the test works as it should.
The problem is, I would like to check if the login was successful and save it in a testing report without a need for me to see the process trough in person. I figured most valid way to ensure login success is to see if PHP code have created variable $_SESSION['logged_in'] = true as it does when login process is successful. Is there any way for me to seek through $_SESSION variables with Java in my Selenium Webdriver test class?
Honestly, don't know php, but in js e.g. any js variable can be recieved using next code
driver.executeScript("return someGlobalVar");
Why you need to verify exactly value of $_SESSION variable?! I think successfull login verification can be done using other ways e.g.: a. Verify that page contains some valid information related to currently logged user (e.g. name, other fields on the page) b. Verify url c. By getting response from server (or smth like this) etc. Hope this will help.
i am having one jsp file with the following code
String name=request.getParameter("user");
if(name==null)
name=(String)request.getSession().getAttribute("name");
else
request.getSession().setAttribute("name", name);
i assume if the page get any request with user as parameter, it will save the value to that particular user session and in case the get request is not having any 'user' parameter it will try to read the user value from the session. The code is working perfectly when i host it from my local server(glassfish).
But when i upload it into some remote host, things are getting weird.
When i hit the page with parameter 'user', its saving the value in the session. But then again if i hit the page from some other browser(or after clearing cookie), its retrieving the previous value saved, instead of returning null
Am i doing something wrong, actually im pretty new to Java EE.
You cannot get previous value saved unless
1) Your session is not finished and same session is getting extended. Can you explain how you are clearing the cookies.
2) Are you typing the URL or trying to refresh the page after deleting the cookies.