• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

How to handle login failure and 403 error programmatically?

 
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello to JSF developers!

After I read a little 'JSF for nonbelievers' from IBM I am much more confident about what I do!
Because at first I found on the Internet that Tapestry and Servlet is better than JSF. Now I know that JSF is superb because it really utilizes MVC pattern which I conceived doing my best Swing application! JSF is really like Swing I state. JSF is step ahead and will be recognized in future I think!

Actual question is how to handle error code like 403, login failure programmatically?
I have my very secure FORM based authentication. Once unauthenticated user accesses his profile login form is presented. Then user types his wrong credentials and the same login page is presented.
In my web.xml there is:


I need to handle login failure, 403 programmatically in order to give corresponding error message like: 'You don't have permission to access this page'.

Thank you!
 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I suppose you use j_security_check for authentication?
You can try to use a custom bean instead. This way is more JSF-native, I think. For example:

And in LoginController bean:
 
Bin Smith
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Vladimir for reply!

I can't use this way because Tim Holloway says it is not secure at all. He states that login system should be done automatically by container's built-in login implementation only. Because it is the only secure way!
I managed to achieve this. Once user clicks secured link he is automatically sent to login form, if user types valid credentials and his role allows access to this page system itself redirects him to requested resource. No need for developer to redirect user somewhere. AND IT WORKS even if I press browser's back button after login failure. If user role does not allow him to get to requested page he is sent automatically to my forbidden.xhtml page.
I probably can't anyway to handle login error automatically. That's why on loginError.xhtml, forbidden.xhtml I simply provide link to page where he was before clicking on secured link.

BUT, I don't like the idea that I should provide link 'User Profile' to secured page without user is logged in. It means that regardless of role user can see all possible links because I must provide them because there is no direct link to login page.
On site JavaRanch user is logged in at first and then he can see link "My profile", "My posts".
The question is how to hide links to secured pages from unauthenticated users?
It sounds as though I should provide separate page where there are all links for all roles! Nobody does it.
Also I don't know what to write in welcome page after user is registered because my index.xhtml is welcome page for everybody.
 
Saloon Keeper
Posts: 28766
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First I get pedantic: backing beans are NOT Controllers, they are Models, so seeing a backing bean named xxxxController makes me itch.

Then I become a weasel: I won't say that server security is the ONLY way to have a secure webapp, just the only one likely to be secure (based on real-world experience) unless you have a full-time staff of software security specialists at your disposal.



There are 2 separate login pages provided by the built-in security platform - the login page and the loginfail page. If login fails, the loginfail page is displayed. It can serve as a login page as well, so my loginfail page usually just says "Login Failed. Please Login" and has a userid/password form. In other words, it's a clone of the original page except for the additional text. Also note that once logged in, you don't get directed to the "welcome" page by default - you simply go to whatever secured URL you were requesting when you were diverted to login.

I do not recommend placing any links, applets, animations or other extensions off of the login page. I keep my login pages minimalistic to reduce possible security exploits. Not to mention complaints from users who think they logged in but didn't because they clicked a menu on the login page.

JSF doesn't support role-checking at the tag level like Struts does, but you can do something similar without too much effort:


Where "user" is a backing bean whose "isAuthenticated()" method looks something like this:


JSFUtils is a general-purpose class I code to hide ugly details. Keeps framework-specific code out of the POJOs and makes it easier to test offline.

You can design similar functions to check based on individual roles as well.
 
Vladimir Mokrozub
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I get it right, you want to get rid of loginError.xhtml and forbidden.xhtml?

Maybe an ugly solution, but you can try to set a request parameter like this:

and add a check for fail to login.xhtml:


As for hiding elements, you can check if user is authenticated by comparing request.userPrincipal to null in the rendered attribute of the appropriate elements on the page.
 
Bin Smith
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much for replies!

I decided to preserve loginError.xhtml and forbidden.xhtml pages. Now I know that they can only be clones of login page with appropriate error message.

But I don't understand how to force user to login in order to know his role and which pages he is allowed to visit!
Links to these pages should be displayed on my page only if user is authenticated.

Can I provide link to login page on top of my template or how to resolve question in bold?
Thanks for this.

But I also don't know very well which scope it is better to use.
I have my register page and user profile page where almost every control has <f:ajax> element. These pages both use the same view scoped backing bean!

Is it worhty to create separate request-scoped bean for a few methods that can be put in request scope?
Of course these methods are in session scoped bean now!

And finally, as far a I know in MVC controller is what catches events fired by my ui components from view. Controller is also called listener.
I think that managed bean is just controller as it acts like listener. State of web app is kept in model (entities)
Model administration is done in EJB, CDI, they take EntityManager to update model or they invoke web service.
Anyway EJB controls transaction, security, concurrency to update model properly.
Model is where state of program is kept in web site but not in standalone GUI(Swing) where model defines state and behaviour of program!
 
Tim Holloway
Saloon Keeper
Posts: 28766
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The login page has no URL. Therefore you cannot provide a link to it.

The login and loginfail pages are not controlled by the webapp, only defined by it. The login page will be presented by the webapp server whenever a user requests a secured URL (as defined in the webapp's WEB-INF/web.xml file) IF the user is not currently authenticated (logged in).

This is one of the great strengths of the container security architecture. You cannot forget to ensure that the user is logged in because YOU do not control login, the server controls login. The server presents and processes the login and loginfail form pages, and unless the user passes the server's authentication tests, the application never sees the offending URL request at all because the server will reject it. Thereby ensuring that attackers cannot exploit possible bugs in the application in order to bypass security.


But I also don't know very well which scope it is better to use.
I have my register page and user profile page where almost every control has <f:ajax> element. These pages both use the same view scoped backing bean!

Is it worhty to create separate request-scoped bean for a few methods that can be put in request scope?
Of course these methods are in session scoped bean now!



Use Session scope when you need to hold data that appears in more than one View (web page).

Use View Scope when you need to hold data that is only processed on a single View (web page).

Request Scope is almost totally useless in JSF because Request Scope objects are destroyed on every postback and therefore cannot retain state.


And finally, as far a I know in MVC controller is what catches events fired by my ui components from view. Controller is also called listener.
I think that managed bean is just controller as it acts like listener. State of web app is kept in model (entities)
Model administration is done in EJB, CDI, they take EntityManager to update model or they invoke web service.
Anyway EJB controls transaction, security, concurrency to update model properly.
Model is where state of program is kept in web site but not in standalone GUI(Swing) where model defines state and behaviour of program!



You think wrong. In JSF the master Controller is the FacesServlet. Sub-Views (components) have Sub-Controllers that are contained in the taglib implementation code. JSF Listeners aren't really Controllers at all. Controllers are the part of the MVC architecture that reflects the state of the Model into the View and reflects the changes to the View (control values) back into the Model. Backing beans provide methods that the Controllers use (set/get, Converter, and Listener methods), but those methods don't actually provide the data transfer process, which is what the Controllers do.

Note that action methods are not part of MVC at all. They are business methods attached to the Model. MVC doesn't define how data got in and out of the MVC subsystem, how or if it gets persisted or what business functions are provided. MVC is purely about the UI/Model synchronization process.
 
Bin Smith
Ranch Hand
Posts: 514
1
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Tim Holloway for your reply!

Probably I caught it!
Controller carries state of model into view and changes in view it carries back into model. And Controller is FacesServlet.
FacesServlet uses getters and setters to carry ui component's value into bound property of model.

The login page has no URL. Therefore you cannot provide a link to it.


JSF doesn't support role-checking at the tag level like Struts does, but you can do something similar without too much effort:
view plaincopy to clipboardprint?
<h:commandLink id="menu1_secure" value="Secure menu 1" action="..." rendered="#{user.authenticated}"/>


It means I cannot provide link to login page and I don't display any link to secure page because user role is Guest therefore no link is rendered.
How to hide links like 'My Profile', 'My Post' to secured pages from Guest and at the same time offer Guest to authenticate himself? How to do this without login.xhtml
Stop, I probably can provide on my page stupid link 'Login' that forwards user to empty secured page which uses <f:event type='preRenderView' listener='mybean.redirectSomeWhere'> to redirect user to page where he was before clicking on 'Login' link.
It is the best I can make up!
Can I use link 'Register' to register.xhtml inside login.xhtml in case user was not registered.
Finally, don't you know how to forbid user to get to login.xhtml typing path directly in browser?
Thanks!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic