In a JSF page a select is populated based on logged in user privileges.
The aziende4ReportList contains only data related to the logged in user
<h:selectOneMenu id="comboAziende" value="#{provaController.azienda}" required="true" >
<f:selectItems value="#{provaController.aziende4ReportList}" />
</h:selectOneMenu>
I thought the data sent to the server with the post could be tampered so I did a check sending a value outside the list and I got a validation error.
Can I be sure JSF checks the incoming data accepting only values that can be inserted in the form it produced previously ?
Can I be sure JSF checks the incoming data accepting only values that can be inserted in the form it produced previously ?
That's correct. Tampering the request with an unlisted dropdown list value would only result in "Validation Error: Value is not valid". It's not only that, JSF also re-checks all disabled and rendered attributes during postback. So even if one used JavaScript to manipulate the disabled attribute, or used browser's builtin HTML DOM editor to manipulate the HTML elements, it would still not pass as it's not valid according the JSF view state.
Your question title is by the way confusing, so I'll ignore that part for now. To the point, server side checks are absolutely necessary, no excuses, this is regardless of the server side language/framework used. However, JSF does already a lot of them, including XSS and CSRF.
Related
So I was testing my JSF application and suddenly I can't pull the value I stored in the bean anymore. I switched from Request scope to Session scope and I was able to pull a value, but it seems to be the value of the last page I clicked.
File structure goes something like this:
About.xhtml sets a page number stored on the Bean and then calls Layout.xhtml which calls Bean.Method() to get Content_About.xhtml to load some text to the page depending on the page number declared in the About.xhtml file.
To my understanding the Request scope should work as long as I don't need to access the stored information past the page loading, but it is acting as if the page number hasn't been set.
With a Session scope declared, it loads the text, but it seems as if it is building the page, then changing the stored value in the bean. It requires that I click on the page I want twice to get the correct information on a page.
Any help appreciated.
Further investigation: I am able to do the following, but it shows the correct page number before and after the method call to load the content.
Page Number: #{MainBean.getPage()}
<h:form>
<ui:include src="#{MainBean.Content()}"></ui:include>
</h:form>
Page Number: #{MainBean.getPage()}
Accepting that the ui is built first, using the default value of the stored variable, I proceeded to set the value in the ui declaration when layout is called.
I had something like:
#{MainBean.setLevel(0)}
#{MainBean.setPage(1)}
<ui:include src="Layout.xhtml"></ui:include>
and changed it to:
<ui:include src="#{MainBean.setLayout(0,1)}"></ui:include>
public String setLayout(int lvl, int pg)
{
setLevel(lvl);
setPage(pg);
return GetPath()+"Layout.xhtml";
}
This allows the bean's variable to be set during the construction of the ui and carry forward through the rest of the request.
Could you please give me some directions on how to pass values from disabled or readonly input fields in xhtml page to requestscoped bean?
I thought that I can bypass jsf checking the field state by disabling
fields in javascipt code on form open and then submit form, but that
did not help too.
I cannot use view scope, because I would have to set then almost
every page in my application in view scope.
It is very inconvenient to use hidden fields for this purpose,
because it would double the number of fields on the page.
Maybe I have missed some clean solution?
Thank you in advance for any help.
Disabling fields using JavaScript didn't work probably because you didn't enable them just before sending a form. Values of disabled fields are not sent (see input documentation).
For example the following code works perfectly well:
<h:form>
<h:inputText id="disabledinput" styleClass="disabled"
value="#{someBean.property}"></h:inputText>
<h:outputScript>
$('.disabled').attr('disabled', 'disabled');
</h:outputScript>
<h:commandButton action="#{someBean.action}"
onclick="$('.disabled').removeAttr('disabled'); return true;"
value="Submit" />
</h:form>
onclick attribute executes JavaScript code that enables input just before sending the form.
If you use AJAX request you have to restore disabled state using oncomplete or similar.
The problem with this solution is that user can manipulate the value. E.g. she/he can use javascript console in a browser to change the input to enabled or use some tool (e.g. curl) to prepare or tamper request. So if the value is sensitive or should never be changed by the user consider storing the value in the session.
IMHO if the value was provided by the user in one of the previous steps then it doesn't matter that much. However, if value is calculated (like total value or something) you should not depend on its value as users could change it. Personally I would prefer to store the value on server side (in session or in flash).
We're using JSF 2.0 on WebSphere v8.5 with several component libraries PrimeFaces 4.0, Tomahawk 2.0, RichFaces, etc.
I am looking for generic mechanism to avoid form re-submission when the page is refreshed, or when the submit button is clicked once again. I have many applications with different scenarios.
For now I have considered disabling the button with a piece of JavaScript in onclick attribute, but this is not satisfying. I'm looking for a pure Java implementation for this purpose, something like the Struts2 <s:token>.
I am looking for generic mechanism to avoid form re-submission when the page is refreshed
For that there are at least 2 solutions which can not be combined:
Perform a redirect after synchronous post. This way the refresh would only re-execute the redirected GET request instead of the initial request. Disadvantage: you can't make use of the request scope anymore to provide any feedback to the enduser. JSF 2.0 has solved this by offering the new flash scope. See also How to show faces message in the redirected page.
Perform the POST asynchronously in the background (using ajax). This way the refresh would only re-execute the initial GET request which opened the form. You only need to make sure that those forms are initially opened by a GET request only, i.e. you should never perform page-to-page navigation by POST (which is at its own already a bad design anyway). See also When should I use h:outputLink instead of h:commandLink?
or when the submit button is clicked once again
For that there are basically also at least 2 solutions, which could if necessary be combined:
Just block the enduser from being able to press the submit button during the submit and/or after successful submit. There are various ways for this, all depending on the concrete functional and design requirements. You can use JavaScript to disable the button during submit. You can use JSF's disabled or rendered attributes to disable or hide the button after submit. See also How to do double-click prevention in JSF 2. You can also use an overlay window during processing ajax requests to block any enduser interaction. PrimeFaces has <p:blockUI> for the purpose.
Validate uniqueness of the newly added entity in the server side. This is way much more robust if you absolutely want to avoid duplication for technical reasons rather than for functional reasons. It's fairly simple: put a UNIQUE constraint on the DB column in question. If this constraint is violated, then the DB (and DB interaction framework like JPA) will throw a constraint violation exception. This is best to be done in combination with a custom JSF validator which validates the input beforehand by performing a SELECT on exactly that column and checking if no record is returned. A JSF validator allows you to display the problem in flavor of a friendly faces message. See also among others Validate email format and uniqueness against DB.
Instead of creating a token manually, you can use BalusC' solution. He proposed a Post-Redirect-GET pattern in his blog
Alternative solutions can be found in these answers:
Simple flow management in Post-Redirect-Get pattern
How can Flash scope help in implementing the PostRedirectGet (PRG) pattern in JSF2.0
<!--Tag to show message given by bean class -->
<p:growl id="messages" />
<h:form>
<h:inputText a:placeholder="Enter Parent Organization Id" id="parent_org_id" value="#{orgMaster.parentOrganization}" requiredMessage="Parent org-id is required" />
<h:commandButton style="margin-bottom:8px;margin-top:5px;" class="btn btn-success btn-block " value="Save" type="submit" action="#{orgMaster.save}" onclick="resetform()" />
</h:form>
public String save() {
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getFlash().setKeepMessages(true); //This keeps the message even on reloading of page
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Your submission is successful.", " ")); // To show the message on clicking of submit button
return "organizationMaster?faces-redirect=true"; // to reload the page with resetting of all fields of the form.. here my page name is organizationMaster...you can write the name of form whose firlds you want to reset on submission
}
I am very new to JSF. I have the following requirement:
On click of a commandButton, call a backing bean method to check if there is some data present satisfying the condition.
If yes, confirm from user for overwrite.
If user says OK, call the same method of backing bean with some parameters set to tell the program to overwrite the data.
What I am doing is:
having action of the commandButton as the method name.
in the backing bean method, check if we have come with certain condition, check if the data is already present.
If yes, go back to page and ask for confirmation.
If confirmed, call the click method of the button.
The problem is, when I come back to the page, the inputFileUpload component on the page loses its value.
What can I do to achieve this? Please help.
This is fully by HTML specification and completely outside control of JSF. It's by HTML specification for security reasons not possible to (re)display the value of a HTML input file field with a value coming from the server side. Otherwise a hazard scenario as shown in this answer would be possible.
You need to redesign the form in such way that the input file field is not been updated during confirmation. You can use among others JavaScript/ajax for this: just submit the form by ajax and make sure that the input file field is not been updated on ajax response.
The most popular page in my JSF/PrimeFaces web app is a page with p:dataTable with data spanning date ranges (and yes, FROM and TO p:calendar are used for filtering the data along with p:inputText and p:autoComplete components, when/as necessary).
I would like to poll for changes in the data listed in the dataTable for selected dates (date range). I would like to render an Update or Refresh commandButton/Link ONLY IF data has changed for the current view for any/every user.
When a given user makes an update to data, I would like to inform other users in any/all other sessions that this data was changed, and if user(s) is/are viewing that data on a page/view via dataTable (or detailed view), then user can click Refresh button to see the update, but the Refresh button/link is only rendered via AJAX via polling. Of course, I want this 'action' to be initiated or some flag (or POJO may be more appropriate) to be stored on server ('List dataThatWasUpdated'), and polling would check this 'per' user (like the polling-Notifications implementation that I already have in place, which is working perfectly). During polling, this list will be scanned, and if user is viewing any of the data that is in the List, then Boolean will be set on another managedBean to render the commandButton/Link. This List would be set to null after each polling.
In the near or distant future, after I migrate to CDI, I will do this via CDI and server-sent-events (SSE) via HTML (and Java EE CDI, of course), but for now I am considering using or adding p:poll to give user the opportunity/option to refresh the view (since data has been updated by another user).
Please confirm my thoughts/design and/or advise. Thanks.
p:poll is fine but a WebSocket/Comet Framework could be nicer (and not really complicated to add). And as you are using Primefaces, you could use Atmosphere (http://atmosphere.java.net). They had a p:push to achieve such a goal.