Problem with JSF forwarding and security constraint - security

I'm making a web application in which certain pages are login-protected. I have created a JDBC security realm in glassfish for this, and used Form authentication (Similar to the method described here)
I'm using Navigation rules to redirect the user to the secured areas of the website:
<navigation-case>
<from-outcome>showResults</from-outcome>
<to-view-id>/SecureUser/Reservation/New/AvailableResults.xhtml</to-view-id>
<redirect/>
</navigation-case>
(etc...)
This works fine. But if I skip the redirect tag in the navigation-case, then the URL of the page doesn't change. And in that case, an unauthenticated user is able to access the secured page.
What is the best way to go about this? Making sure that the page is redirected instead of forwarded is good enough? Should I write code in every secured page that checks whether the user is logged in or not?

Using POST for page-to-page navigation is considered bad practice. Don't use JSF h:commandLink or h:commandButton for simple page-to-page navigation. Both generates a POST form which is totally unnecessary and SEO-unfriendly for simple navigation. Rather use h:link or h:button instead. It renders a plain vanilla GET link and GET form respectively.
If you are submitting a POST form anyway and the result page is different from the form page, then using PRG (Post-Redirect-Get) pattern is considered good practice. You can use <redirect/> for this.

Related

FullAjaxExceptionHandler not redirecting to custom error page (URL stays same) [duplicate]

In OmniFaces, the FullAjaxExceptionHandler, after having found the right error page to use, calls the JSF runtime to build the view and render it instead of the page that includes the AJAX call.
Why this? IMHO it would be simpler to just perform a ExternalContext#redirect()? Are there specific reasons to do this?
We are writing our own ExceptionHandler based on FullAjaxExceptionHandler and wanted to understand the reason behind this design.
The primary goal of the FullAjaxExceptionHandler is to let exceptions during ajax requests to behave exactly the same as exceptions during non-ajax requests. The developer must be able to reuse the error pages across both conditions without worrying about the condition while implementing the error pages.
A redirect isn't part of the normal flow during non-ajax requests. The default <error-page> mechanism in web.xml performs a forward to display the error page, not a redirect. If a redirect was performed, all error page request attributes such as javax.servlet.error.exception would get lost and render as null. Moreover, normal practice is to place error pages in /WEB-INF to prevent endusers from being able to directly access (and bookmark and share) them. A redirect would require them to be publicly accessible, which indicates a major design problem (is the intented target page actually a real error page?).
If you really need to perform a redirect to/from your error page, either homegrow a custom exception handler which explicitly invokes ExternalContext#redirect() and doesn't utilize web.xml <error-page> mechanism, or add a <meta http-equiv="refresh" ...> to the HTML head of the error page in question (example here).
In case you actually intended to redirect to some login page when a ViewExpiredException occurs, then you should realize that there's a big difference between the cases of "User is not logged in" and "Session/view is expired". For the former, you should not be catching ViewExpiredException at all, but use a simple servlet filter which checks if the user is logged in and redirect accordingly, long before the FacesServlet is invoked. A normal authentication framework (JAAS, Shiro, Spring Security, etc) also works that way.
See also:
What is the good approach to forward the exception from servlets to a jsp page?
What is the difference between redirect and navigation/forward and when to use what?
Why use a JSF ExceptionHandlerFactory instead of <error-page> redirection?
Check if session exists JSF
Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same

How to always show the same URL in JSF 2.0?

I'm making my term paper and I have some doubts in my way.
Now my main question is: how to always shoe the same URL to users using JSF 2.0 (Apache Tomcat 7, JSF 2.0, Java 6)?
I have dozens of pages, one of login, others with the features of my website, but I want that just one URL be showed to users. What I want is:
If user go to login page, the url will be:
mypage.com/
If user login with succesfull, the url will be:
mypage.com/
If user do any thing inside system, the url will be:
mypage.com/
Note that I always want "render" (this is the right meaning?) a different page, but show the same URL to user.
How I can do that? Page Forward?
Doesn't necessarily mean it's a bad thing to maintain your url static.
If you use page forward, you're currently in other url, even browser's address bar doesn't reflect that. With page redirect (POST-REDIRECT-GET pattern) you get the new url on it, however it requires one step more from http protocol point of view, so it's a bit slower. Both of them allow you going to an specific view with its url (bookmarkable app) and also are considered into JSF navigation case based system.
What actually could be considered a pitfall, but could be used depending on the case, is to have your application's main frame (could be the main template from JSF's point of view) in an url and just rerender some of its content via ajax. That doesn't allow you to have bookmarkable pages, however it could be even faster than performing a page forward if you're interested in maintaining many parts of your view with the same content.

Tuckey UrlRewrite filter doesn't work properly with JSF forms

I integrated Tuckey UrlRewrite filter in my JSF application. My URLs now look like:
http://localhost:8080/myapp/page
instead of
http://localhost:8080/myapp/faces/page.xhtml
The problem is that my JSF forms submits to the old url
http://localhost:8080/myapp/faces/page.xhtml
and I am getting a FacesFileNotFoundException.
How can I solve this issue?
You've to implement a custom ViewHandler and override the getActionURL() method to return the desired form action URL. That's where the forms get its action URL from. This is by the way also what PrettyFaces, the JSF URL rewrite solution, does. You may want to use it instead of reinventing the same wheel. It's by the way open source, so you could just peek around in its source code to see how they did it.

JSF 2.0 : change default behaviour from page forward to page redirect

I know there are some advantages in using page forwarding as it is the default in JSF.
I also know how to set redirect for some pages using 'faces-redirect' in the implicit navigation or the tag in the faces-config file.
I searched a lot on internet but I didn't find an easy and straight way (such as a configuration parameter) to enable redirect for all pages.
The reason I would like to use page redirect everywhere is the following: if every page is asked whit its url the container can be used for page authorization without the need of additional security library. Don't know if it can be a good idea, but performances are not an issue in this moment and using container security can save development time for the first release.
You can achieve this with a custom ConfigureableNavigationHandler. You can find a kickoff example in the answer to this question: JSF 2 and Post/Redirect/Get?
However, I have the feeling that you're designing page-to-page navigation the wrong way. You seem to be using POST requests for simple page-to-page navigation. If you fix them to be GET requests, then you don't need to worry about this. So, use <h:link> instead of <h:commandLink> for page-to-page navigation. This way you don't need to implement the PRG. See also When should I use h:outputLink instead of h:commandLink?

how to create a link to a JSF page from outside the application

I am working with a JSF application that posts on every mouse click, so if you get 5 pages deep, your url stays the same.
now i need to link to one of these pages from outside of jsf. what can i do?
(i am new to jsf)
Navigation rules use forward by default, that's why the URL does not change.
Use http://site.com/ctx/page.jsf to access a given page. *.jsf is the mapping of your faces servlet to in web.xml (it can have different value in your configuration, but normally it is *.jsf or /faces/*
i dont know if ive got it right but as much as i understood it you need to use GET instead of POST this time, right?
in my current project we still use JSF 1.2 and that is achieved by PrettyFaces (http://ocpsoft.com/prettyfaces/) by us. do you mean that?

Resources