How to display message after form submit and be idempotent - java

when a form is submited that inserts a record into the database and the operation was successful, I do a redirect and then pass some parameters in the Url to display the newly inserted record along with a header message (i.e., "Insert was successful").
response.sendRedirect(yPage + "?pid=" + ipd + "&feedback=" + form.getFormFeebackSB() );
I would then display in jsp like:
<c:out value="${param.feedback}" />
I use a redirect instead of a forward because I want the operation to be idempotent. When I used forward users who hit refresh after a successful insert most often always clicked retry on the warning popup and it resulted in duplicate inserts.
Our IT department then discovered that I had a XSS vulnerability:
page.jsp?feedback=%3Cscript%20type=%22text/javascript%22%3Ealert%28%27xss%27%29;%3C/script%3E
So I changed to this:
<c:out value="${param.feedback}" escapeXml='true'/>
but now any <br> in my FeedbackSB get escaped and I end up with a header message as such
Insert was successful<br>An email was sent to Joe<br>Now Complete the XYZ Form;
what is the standard way to pass messages back to user, while keeping any submits idempotent and protecting against XSS?
EDIT:
I searched Flash Scope and came across this http://blog.smartkey.co.uk/2011/01/implementing-flash-scope-in-java-web-applications/
Since my application would require a lot of work to incorporate a framework, the filter mentioned in that link was easy to incorporate and was able to implement flash scope with very little effort.

Don't pass the message itself in a redirect. Store the message under a unique key in the session, redirect with the key of this message as URL parameter, then go to the session, get the message, and display it.
I would also remove the message from the session immediately: if the user refreshes, there is no reason to tell him again that the insert was successful.
Most of the MVC frameworks do that for you, using what they usually call a Flash scope (session attributes that are removed from the session as soon as they've been retrieved).

Related

In Wicket 9, when the user's session expires in certain pages, they are redirected to the login page not the Session Expired page

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.

how bank maintain session by allowing single login at a time

I am using struts2,jsp,hibernate to develop my application . Can any one tell me the best way to maintain session for allowing single login per user. do i have to store all user login session id in context or any other way to that? please explain about this
I've seen this done in one project, using a Servlet Filter and the database. As part of your login process you create an entry in a db table. Call it a "LoginSession" table or whatever you want. Also as part of creating the record in the table, invalidate any previous entries in that table for the same user. Associate the users current session id cookie with that entry. Then in your Servlet Filter, which you'd have filter every request, check the database, to see if this request has a still valid entry in your "LoginSession" table. If so let the request continue. If not, redirect them to the home/login/logout page of your choice.

Reload/History behaviour in Get and Post request?

I went thru http://www.w3schools.com/tags/ref_httpmethods.asp to read
about read vs post.Here is the description
To clear confusion, I am just taking scenario where user creates the customer on page 1(with the submit button) and
navigates to success page(page 2).
For reload (say user press F5 on success page) point, Get request is said to be harmless where in post request
"Data will be re-submitted".
My understanding in both request (GET/POST), data will be resubmitted
. so in customer scenario, two customer will be created when user
press F5 on page whether its post or get. So as per my
understanding, Data will be re-submitted in both GET/POST request and
none is harmless.Please correct my understanding if it is wrong?
For History point. It is said in GET request ,"Parameters remain in browser history" and for POST request
"Parameters are not saved in browser history". My question is if request parameters are not saved in
browser history in post request, how on click of F5 on success page duplicate customer is created. Are they stored
at some other location instead of browser history in post request?
I'll try to explain point by point:
About GET being harmless: Method GET is supossed to de idempotent, that means: given the same url and the same parameters it always should return the same result (user=34,date=01-07-2013 should return the same page) and SHOULDN'T change anything (do nothing more than a sort of query with "user" and "date"). Of course is quite common to break this rule and actually change the internal state (do an update or the like) that is the case that you're mentioning (page1 --> page2 creating something). POST requests don't have that requirement and are meant to change the internal state.
About parameters remaining in browser history: What they really mean is that in the GET request parameters are contained in the URL itself ( mysite.com?user=34,date=01-07-2013 ) so if you save the URL you also saving the parameters. In a POST request parameters go in the body of the request rather than as part of the URL; so you're right, old browsers used to only store the URL, nowadays browsers are optimized to store those POST parameters in an internal cache.

How to programmatically send a HTTP request with parameters? [duplicate]

This question already has answers here:
How to use java.net.URLConnection to fire and handle HTTP requests
(12 answers)
Closed 7 years ago.
If I use a browser to send information to the server (for example using a log-in, password page), I just fill the user text-box and the password text-box and clicking on the log-in button.
I would like to send this information but without having to use the browser. I would like to 'fill' the text-boxes but without having to do it manually in the browser. May be using a Servlet.
My question is: How to send information in text-boxes, for example, to a website, doing it from a Servlet?
why not just make a call to the URL from Java using a URL like http://your.domain.name/your/servlet/path?userFieldName=THE_VALUE_YOU_WANT_TO_PASS&passwdFieldName=PASSWORD
The servlet will feel like the values are coming from those boxes.
Or you may want to dive into Apache HTTP Client to mimick a request sent from an client.
uh..oh.. are you doing functional testing? Why not look into JMeter?
Updates as per comment
You need to know what actually form submission does? It basically forms a query string composed of Key-Values (KV) pair.
So, if you have a a text field named tfield where user has typed some text, and there is a drop down named, ddfield where user has selected optionX which has value optionX-Val. And this form gets submitted to a URL, http://my.domain.name/my/servlet -- the browser will send a request which will look like
http://my.domain.name/my/servlet?tfield=some%20text&ddfield=optionX-Val
If you want to mimic form submission, you will have to manually create a URL that has a request string containing all the fields and their values as FIELD_NAME=FIELDVALUE ordered pair separated by ampersand (&)
ah, great idea. If you use Firebug (a Firefox extension), open the NET panel in Firebug, make a manual submission of the form that you wanted to mimic. See what request is posted when you submitted the form. It will have exact URL format that you are after. Copy this URL, replace the values and make fake submissions as much as you want.
Hope this helps.
It is not clear to me what you really up to. I assume that the servlet will be the one who will send the data. Here some examples.
Using setAttribute then Forward the request
//On your servlet
request.setAttibute('user', 'admin');
request.setAttribute('password', '123');
getServletContext().getRequestDispatcher("page.jsp").forward(request, response);
//On your jsp page get the value using EL
<span>${user}</span>
Using session
//On your servlet
HttpSession session = request.getSession(true);
session.setAttribute('user', 'admin');
session.setAttribute('password', '123');
getServletContext().getRequestDispatcher("page.jsp").forward(request, response);
//On your jsp page get the value using EL
<span>${user}</span>
The above example is intended to work within the web application. To send information to another web application, which expecting a request. See sample below.
//On your jsp or servlet, you can also do the same within web application
request.sendRedirect('http://example.com?user=admin&password=123');
//on your jsp #example.com
<span>${param.user}</span>
If this is not what you mean, adding more details will be a help.
a servlet takes care of the other end: it's basically a handler for http requests that lives inside a servlet container. If I understand you correctly, you're wanting to send an http request. You can do that using command-line tools like curl, or if you want to stay within java land, you could try this example on exampledepot. Use your favourite search engine to search for more examples, e.g. with search terms such as "sending GET requests through a url".
In your situation, where you need to send information for username and password, you would need to look at the html and find the url for the form element's action attribute. Then you need to find the names of the username and password fields. Using these names as url parameters, you can construct a GET request that mimics sending a form.
NOTE: usually storing a password in plain text in code and/or sending it in plain text to a website is not a good thing to do.
Just in case anyone is interested, there is a plugin for Firefox called Tamper data. With it you can stop the sending of and http request and modify it. It will show you the "url" you need for sending the params, the values they currently have, and their name. You can check it out here. After that you can use a request.sendRedirect('url you got from Tamper Data');

Prevent user from opening JSF page in more than one tab/window in a browser

Is it possible to prevent user from opening JSF page in more than one browser tab or window?
I agree with the accepted solution, but if you still have to do it, these steps worked for me (pseudo code/pseudo python):
On the JS side:
if tabId not set:
. generate random number
. set property in sessionStorage
otherwise:
. get it from sessionStorage
make an ajax callback and send tabId
onError:
. alert();
. close current tab (if possible);
. logout
Backend:(JSF):
Create custom filter:
if request contains the tabId info:
if it matches session's tabId: (being tabId not null)
sent response status code to an error such as forbidden
Optionally invalidate session
otherwise apply session filtering (do nothing)
#BalusC The problem concerns old JSF application that is entirely stateful. Why try to figure out some way to inform users that openning the app in two separate tabs is potentially dangerous. In no way can we change session managed beans to request managed beans.
Make all those beans request scoped, install Tomahawk, add <t:saveState value="#{bean}" /> for every bean to every view of which you'd like to retain exactly the same bean state in the subsequent request. This works independently across tabs/windows.
Without Tomahawk, the alternative would be adding <h:inputHidden /> for every bean property which you'd like to retain in the subsequent request. I can however imagine that this may produce nasty boilerplate code when there are much or when they aren't of the standard EL types (for which you have thus to create a Converter). But that's what you get paid for.
One scenario I have in mind:
Put a javascript component in the page that will constantly sending heartbeat to the server via AJAX. As long as there are heartbeat sent from browser, this page will be flagged as 'currently_viewing'. And as long as a page have that flag on, other requests to that page should be rejected.
The detail may be a lot messier than this simple story (e.g. you might need to have some sort of 'page id' to be sent with the heartbeat), but you get the idea (... i hope :).
Everything is possible as long as you are willing to pay the price.

Categories

Resources