Is (isUserInRole()) the easiest way to attach user permissions/security to a JSF button?
Asked Answered
C

1

8

I recently developed a tomcat web app in JSP that uses declarative security (server.xml/web.xml) tied to the company's Active Directory. I was asked to add JSF support to the fledgling project. It was a simple matter to convert the login form to jsf, and the security model still worked.

An associate asked if I could allow a wider audience to view one of the reports, but render the action buttons only for a smaller group. Being new to JSF, I had to do some research.

I spent about four hours googling things like "jsf button security" and "jsf button permissions" and trying various suggestions that were mostly dead ends. Another associate had suggested using the Spring security model, but I didn't want to deal with a whole bunch of Spring libraries if there was an easier way to do it.

Eventually, I stumbled upon the answer, which was incredibly simple. I only needed to use the HttpServletRequest method: isUserInRole() to determine if the currently logged on user has permission to see the action buttons. I've used HttpServletRequests a LOT over the last ten years, but I don't recall ever learning about that method. With jsf, it's a simple matter to get to that method, as shown below:

public boolean isUserInRole(String role) {
    return (FacesContext.getCurrentInstance().getExternalContext().isUserInRole(role));
}

My questions specifically are: are there any gotchas about this approach I should be aware of, and is there another easier way to do it?

Caterwaul answered 26/5, 2012 at 5:26 Comment(7)
It can be done even simpler in EL without the need for a backing bean: #{request.isUserInRole('foo')}Langsdon
but in a jsf managed bean, you wouldn't have access to the request, right?Caterwaul
I've rarely had the need for it in a backing bean. Just put it on rendered, readonly or disabled attributes in the view.Langsdon
Interesting, in the code I was working with, the developer had already defined a backing bean method to determine if the button should be rendered, based on some state information. So, I needed to combine this with the isUserInRole call. But, you're right, this logical anding of booleans could be done in either the bean or the form.Caterwaul
If you should combine it with more complex logic, than it might be better to move this to a backing bean, IMHO. Because mixing a complex logic with presentation layer is never a good idea.Morrill
@jFrenetic: if you repeatedly need to check for a specific combination of multiple roles, why not just giving exactly those users a new single role? That's the whole point of roles.Langsdon
@BalusC: in my case, it's not combining roles to determine rendering, it's combining the role with a set of state information regarding the item currently being displayed on the page. The state information could potentially change each time the user changes the query parameters.Caterwaul
A
1

If you use Tomahawk as an addon to your JSF implementation most of the controls have a visibleOnUserRole attribute. You can use multiple role names in the value.

Aiaia answered 22/6, 2012 at 15:32 Comment(2)
this is really good info, I didn't really know anything about the tomahawk addon, looks to be some good stuff. One question, if I use tomahawk and primefaces, do you think I can add the visibleOnUserRole attribute onto a primefaces control (e.g. p:commandButton)?Caterwaul
I'm answering my own question about primefaces and visibleOnUserRole with this link: cagataycivici.wordpress.com/2010/03/18/…Caterwaul

© 2022 - 2024 — McMap. All rights reserved.