How do I limit a user from accesing sertain pages in JSF? [duplicate] - jsf

This question already has answers here:
How implement a login filter in JSF?
(2 answers)
Closed 2 years ago.
Like the title says, how do I limit users from accessing certain pages in JSF? I have two different kinds of pages that I want to limit access to. The first one is pages that need parameters to load, would it be possible to redirect if a user tries to redirect access that page without any parameters? The second one is pages that only certain users should have access to. In my app you have the ability to create and edit competitions, however, I only want the host of the event to be able to access the edit page for that event - which at the moment anyone can access if they know the right parameters. Is there something in JSF that lets me do this?

General page access
Have a look at #WebFilter and its doFilter method. Inside you can check if your user is logged in retrieving your session scoped bean from the HttpSession.
#WebFilter(filterName = "UserAuthenticationFilter", urlPatterns =
{
"/sites/user/account.xhtml"
} , dispatcherTypes =
{
DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ERROR
})
public class UserAuthenticationFilter extends HttpFilter
{
#Override
public void doProductionFilter(final HttpServletRequest request, final HttpServletResponse response, final HttpSession session, final FilterChain chain) throws IOException, ServletException
{
final UserBean userBean = session.getAttribute("userBean");
// check if logged in and redirect to login page if not
if (userBean.isLoggedIn()
chain.doFilter(request, response);
else
response.sendRedirect(request.getContextPath() + "/login.xhtml");
}
}
Specific page access
Check your request param either in your #PostConstruct or better in your viewAction or initPreRenderView methods since in the later two you have access to your injected view parameters.
If user does not has sufficient rights to access the data redirect or/and show faces message or do something else.

Related

Injecting a session-scoped bean in JSF2

I'm having some difficulty interacting with a Session-scoped managed bean after a user programmatically logs into my web application.
BACKGROUND:
I have a [javax.enterprise.context.]Session-scoped bean named "SessionHelper" where I place a lot of information gathered from the user as he/she uses the application. In my logon page (which is NOT SessionScoped), Here's a sample of what I'm doing:
#Inject SessionHelper theHelper;
....
FacesContext theContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = theContext.getExternalContext();
HttpServletRequest theRequest = (HttpServletRequest) externalContext.getRequest();
....
theRequest.login(username, password);
....
theSession.method(dostuff);
After this section of code is executed, my application redirects into a protected directory and allows the user (based on roles) to perform their job functions.
When I attempt to "#Inject SessionHelper" into any of my protected resources, my understanding is that I should get the specific SessionScoped instance of SessionHelper that has the data set right after the call to login. This should be available to me for as long as the session (for that specific user) is valid. Unfortunately, the instance I'm getting has none of my "theSession.method(dostuff)" in it.
Am I fundamentally misunderstanding the scope here?
The only thing I could potentially see is that the initial #Inject into my login page is not carried over after the session has been created. If this is the case, is there a way to force a re-injection after the session is created?
As always, thank you very much for your help!!

JSF 2.0; MyFaces; Form submit only with POST

i've got a security question and i don't know, how to do this in JSF.
In PHP i can react on a form submit that is defined as POST, that i only want values via POST so there is no way to get an value via GET from the same name of the field.
Example:
fieldname in form: username
in my PHP site i can get the value via $_POST["username"] but not with $_GET["username"], because i don't implement the GET way, only POST.
So, now i want this in my JSF site too.
The problem is, that i can't only implement POST for all requests, i must react on GET also.
I only want, that my form data will come via POST to my bean and not via GET.
How can i reach this?
With a filter or something else?
For your interest: i'm not able to use JavaScript in my application.
Thanks a lot!
I'm not sure I understood your question but if you just need to check if a method on your backing bean was invoked using POST or GET you can get that information from the HttpServletRequest object like so :
#ManagedBean(name="myBean")
#ViewScoped
public class MyMBean implements Serializable{
public void handleForm(){
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
if(req.getMethod().equalsIgnoreCase("POST")){
//Handle your form data
}
}
Just check FacesContext#isPostback().
if (FacesContext.getCurrentInstance().isPostback()) {
// It's a JSF POST request.
}

JSF PhaseListener viewId always one behind

Im trying to prevent users to access special pages with a phaselistener. for that reason im trying to figure out on which page they try to access.
but my problem is, i only get the page they where before. not the actual page.
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
System.out.println("test1" + fc.getViewRoot().getViewId());
}
and same here
public void afterPhase(PhaseEvent event)
{
FacesContext fc = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
String uri = request.getRequestURI();
System.out.println("uri: " + uri);
}
why is that, and how do i get the pagename the user is trying to access? Not that one that they required one step before, or better the page they are coming from.
It is one step behind because that is the way sequence of HTTP POST request behaves. When you are navigating in JSF application via command buttons each request goes as a post request.
Since you are protecting some resources make sure they are accessed via HTTP GET than you will get exact view id, this can be achieved as
User directly hits the url from address bar of browser.
After a post of jsf app redirect it to the resource instead of simple JSF navigation. POST-REDIRECT-GET pattern falls into this have a look here.
If you are showing some messages after each POST, you might need Flash map for that, which is new feature in JSF2, if you are on JSF1.x hard luck, you can implement flash if you want to.
To conclude catch the view ids on HTTP GET request.
Hope this helps...

j_security_check vs Programmatic Security

I'm building a Web application using jsf, ejbs and jpa.
I currently use form based j_security_check to handle authentication.
I need to implement support for cookies ie "Remember me" option.
Also I want to prevent brute force attacks. ie Lock a certain user after 5 failed logons.
I understand that the other option will be to do it programmatically using ServletFilters etc.
Is there any way of implementing all these Using j_security_check? or should I just switch back to doing it programmatically?
This has to be custom implementation around j_security_check. You can attach a servlet filter with j_security_check
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/j_security_check</url-pattern>
</filter-mapping>
In the SecurityFilter, after security check returns userPrincipal, set further details in session and continue. But if userPrincipal is null, fetch the fail count from database and put the failure message (including fail count) in session, which can be displayed in login page.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Principal userPrincipal = null;
String username = httpServletRequest.getParameter("j_username");
String rememberme = httpServletRequest.getParameter("rememberme");
chain.doFilter(request, response);
userPrincipal = httpServletRequest.getUserPrincipal();
Remember me has to be set at cookies and the value of the variable "rememberme" will be available after the j_security_check is completed. Based upon success or failure in login, cookie can be set.

What to do to restrict the user from seeing the page with out login the website?

I want a page has to appear to user after logged in. But if we use that link we can see the page and its content only thing is that it wont be having user data. what to do to prevent this. what can be done in this scenario ?
You can declare a PhaseListener where to redirect to the homepage instead the user is not logged
public void afterPhase(PhaseEvent evt) {
User user =
evt.getFacesContext().getExternalContext().getSessionMap().get(USER_KEY);
if (user == null) {
FacesContext.getExternalContext().redirect("home.xhtml");
}
}
The phase listener can be defined globally, or at view-level with:
<f:view afterPhase="#{bean.afterPhase}">...</f:view>
(in facelets the attribute is called afterPhaseListener)
Use a ServletFilter to check existence of UserData in Session.
If "yes: then forward else forward to error page.
Another option is to use the rendered attribute on tags to check the existence of UserData object.
I'm not familiar with JSF or if it has built in authentication/authorization. But you should be able to apply authentication/access rules directly on your web server.

Resources