wood burning stoves 2.0*
The moose likes JSF and the fly likes Web application with customized pages Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Web application with customized pages" Watch "Web application with customized pages" New topic
Author

Web application with customized pages

Hadrien Tulipe
Greenhorn

Joined: Jan 23, 2011
Posts: 2
Hello everyone, I'm kind of new to JSF and have some trouble with concepts.

I have to create a web app where users can do several stuff.

I have a list of legit users (in db) which have an arbitrarily number of prerogatives (such as "create new user", "post a thread", "mail other people", etc...).
When an user logs in, I need to display a page that takes into account the authorized actions of the logged user. For instance, a user that does not have rights to create new users should not have the "create new user" form displayed. The number of prerogatives being quite big, I can't "hard-code" a page for each combination, I need to do it dynamically.

In the end, for a logged user, I want to display a page with one form per authorized action and I'm having a hard time doing it with JSF.

What I want to do is when a user logs in, the business logic checks the db for his authorized actions and generate the page accordingly.

How would you do such a thing?

Thank you very much





Eric Ford
Greenhorn

Joined: Jun 04, 2010
Posts: 17
Take a look a Facelets.

In a nutshell, with a templating approach you can easily include/exclude whole segments of a page. Use the "rendered" attribute on individual components to evaluate the current user's permissions and display the appropriate contents.

Eric

Hadrien Tulipe wrote:Hello everyone, I'm kind of new to JSF and have some trouble with concepts.

I have to create a web app where users can do several stuff.

I have a list of legit users (in db) which have an arbitrarily number of prerogatives (such as "create new user", "post a thread", "mail other people", etc...).
When an user logs in, I need to display a page that takes into account the authorized actions of the logged user. For instance, a user that does not have rights to create new users should not have the "create new user" form displayed. The number of prerogatives being quite big, I can't "hard-code" a page for each combination, I need to do it dynamically.

In the end, for a logged user, I want to display a page with one form per authorized action and I'm having a hard time doing it with JSF.

What I want to do is when a user logs in, the business logic checks the db for his authorized actions and generate the page accordingly.

How would you do such a thing?

Thank you very much





Brendan Healey
Ranch Hand

Joined: May 12, 2009
Posts: 218

This is far from obvious and took me a while to figure out also. Let's assume that you
have a login page which authenticates the user. There's likely to be a commandButton
which calls an action= method which is in a backing bean.

If the authentication succeeds you are likely to want any information relating to the
login (& any access rights) to be available session wide, and so you want to store it
in the session map. This would be done by the action= method from the login page.
If you don't know about the session map then you probably want to do a little
homework.

From the login page after a successful login you'll want to navigate to another page
which gives the user a choice of further actions. As the data is in the session map
it can be accessed straight away and as already mentioned you can render controls
using rendered= (i.e. <hutputText rendered="{bean.isLoggedIn} value="Hello, World!"/>).

If there is only limited information stored in the session map, i.e. the username,
then one thing you may want to do is additional processing prior to the rendering of
a page. You can do this by having a preRenderView event on the page (specified by
the f:event tag) which has a listener method that can read the username from the
session map, and then setup additional backing bean properties that determine if
the user can give someone a pay rise etc...

I have personally found it useful to have at least one backing bean per page.

Regards,
Brendan.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

Brendan Healey wrote:.... Let's assume that you
have a login page which authenticates the user.


Let's assume you've just created an application that can be hacked in 5 minutes by a 10-year old kid.

OK, sorry, that was nasty. But the reason I say that is that I've worked with J2EE since before JSPs were invented, and seen more webapps than I can count, including some for military and banking systems. Every last one of the ones that had their own security code had security holes in them, and usually the holes were massive and easily exploitable by unsophisticated users.

I really wish J2EE books would stop using "login screens" as examples of how their stuff works. J2EE has a perfectly good security system build into it that can block a lot of attacks before they ever reach the application at all. It's called container-managed security. It was designed by security professionals, has over 10 years of debugging built into it, is well-documented, easy to use, and its functions are built right into the J2EE API and specfiles.

Container-managed security is a role-based security system. Each user has one or more security roles assigned. For coarse-grained security, you can use those roles to deny access to unauthorized users using methods such as request.isUserInRole(). For fine-grained security you can extend that mechanism by using the UserPrincipal as a secure key into whatever application-based authorization checks you want to implement.

JSF complicates things slightly, since this system's first line of defense is the URL itself, but the "redirect" navigation qualifier can get around that. What I normally do is abstract the security into a separate utility class so I don't have to embed a lot of non-portable JSF-specific code into the app itself. Since the coarse-grained security can be taken care of automatically, I only have to write security code for things such as showing/hiding buttons and menus that the user in question isn't given access to.


Customer surveys are for companies who didn't pay proper attention to begin with.
Brendan Healey
Ranch Hand

Joined: May 12, 2009
Posts: 218
I use container security and had to do a lot of rework of my login processing
code. For example I had some code that increments a login count for the user
and persists this to the db. Pre container security this processing took place in
the action routine of the 'Login' button. With container security though the
action routine in a j_security_check form doesn't fire (I just retried it, and it
doesn't, I can see why) so the question is where do you do the login count
increment and save processing?

I moved all this to a preRenderView in my welcome-file, but there was a big
rethink needed and I had to feel my way along the process in the dark as I'd
not seen anything helpful written down about this, not "container security -
implications from a JSF perspective" at least. Maybe I should write something
myself.

Maybe the OP should keep it simple for the timebeing though! It's easy to forget
how tricky some of this stuff can be for a beginner.

Regards,
Brendan.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

Technically, "login" wasn't part of J2EE. Two main reasons for that are:

1. In the case of Single-signon, the user may have already logged in hours ago to some other server entirely

2. J2EE doesn't assume that there's only one way into an application. Which, in fact, is the #1 security hole in most user-created security systems. They do. Hackers don't.

There is now an explicit "logout" method in the latest J2EE spec, instead of the less subtle session.invalidate() method, but I haven't looked to see if there are any useful adjuncts such as "login listeners" now present.

A good workaround, however, is to maintain a small session object that indicates login status. If the URL has no associated user ID, the user is, by definition, not logged in. If the user ID is not null, check to see if you have created the login tracking session object. If not, you've just logged in. Create the object and do whatever, including redirecting users to a "home" page. Or not, if you want bookmarkable secure pages.

The advantage of this method is it can be done in a simple servlet filter and requires no JSF-specific code.
Eric Ford
Greenhorn

Joined: Jun 04, 2010
Posts: 17
Tim & Brendan - no offense intended but I think your responses have taken this thread in a direction not intended by the original question. Unless I'm mistaken, the original question was more about how to render page elements based on user permissions and not on the totality of web application security. I do not dispute your comments but I suspect you'll have the original poster drinking from a firehose.

Eric
Hadrien Tulipe
Greenhorn

Joined: Jan 23, 2011
Posts: 2
Yes maybe the discussion went another way I meant. The app I am creating has no sensitive data, authentication and authorization are not a top priority. Still these posts make an interesting reading and a good reminder of security issues. For my very simple app, I think I will use the "rendered" jsf tag attribute and a session scoped User bean.

Thanks for everybody's input.
 
 
subject: Web application with customized pages
 
Similar Threads
multi tab problem
Best practice for secure login authorisation
Dynamic Creation of Static Text Components
Form Based Authentication
session object behaves like application (scope)