Role Based Rendering of UIComponents
This example will show you how to conditionally render a UIComponent based on the users role.
Last week during the JSF Book promo on JavaRanch someone asked about this. I promised to put together a quick demo and here it is...
Stuff about this example...
- The Page object creates the conditionally rendered component. This was the only way that I could figure out to make it work. If you can think of another please let me know. I spent some time trying to use an expression but there was no way to tell the value I was getting which component was asking if it should render.
- This simple example uses the Tomcat memory realm instead of a db. For real apps you would want to use a DB realm.
- The login and login-error pages are really simple.
- The test for the page uses mock objects of FacesContext and ExternalContext classes. Quick overview here by Vincent Massol. The latest version of the class mocker (instead of just interfaces) is now at 2.1 but the one included with this download is functional.
Here is the important code in case you don't want to download the example.
JSP Code
<h:inputText id="test" binding="#{page.inputField}"/>
The binding attribute binds the actual component to a UIComponent created by the object tied to 'page'. IOW when the view is being rendered it will get the component by calling 'getInputField()' on the page object.
Java Code
public UIInput getInputField() {
if (authorized()) {
inputField.setRendered(true);
} else {
inputField.setRendered(false);
}
return inputField;
}
private boolean authorized() {
boolean authorized = false;
// if its null try to find it
if(null == context) {
context = FacesContext.getCurrentInstance();
}
// should never happen...
if (null != context) {
// clearly 'foo' is a made up role your check should be
// more valid
authorized = context.getExternalContext().isUserInRole("foo");
}
return authorized;
}


I don't understand why one would do this? I typically use a login page and also I with JSF I use JSTL statements to wrap components that I don't want to reveal (unless the user has the proper role/permissions). For instance, in a typical scenario:
1) User logins in via login page
- get userid/password
- read security file ( LDAP or SQL table)
- if userid/pswd valid store roles and permissions in session object (or FacesContext)
(Note: normally stored in a sercurityPerson object)
2) All subsequent pages use JSTL to hide/reveal
JSF components using "if/else" or "choose" statements.
What does your approach offer that is superior to this technique?
Posted by Kamau Obasi on March 13, 2004 at 04:43 PM MST #
Hi Kuman, not better, just different. The JSTL if/else block is just as effective. One advantage of the approach outlined above is that the role information is in the Java class which might make it easier to maintain over time (I personally find it easier but your millage might vary, as they say)
Posted by Bill Dudney on March 15, 2004 at 09:12 AM MST #