How to properly use isUserInRole(role)
To prevent a user role from performing an action.
- Example 1: The role "administrator" is the only role allowed to perform destroy action.
- Example 2: Any role different from "guest" can perform CREATE action.
In a real case, I have this:
public String delete() {
if(FacesContext.getCurrentInstance().getExternalContext().isUserInRole("administrator"){
//.....the action to perform
}
return "Denied";
}
I wish I could use the annotation @RolesAllowed()
of EJB yet I am not using EJB but ManagedBeans.
So the question is: Is there any way to use many roles at the same time? Some workaround!
Example: If an action must be allowed to 3 roles (administrator, moderator, manager). I am obliged to do :
if (FacesContext.getCurrentInstance().getExternalContext().isUserInRole("administrator")
|| FacesContext.getCurrentInstance().getExternalContext().isUserInRole("manager")
|| .....) {
//....
}
And it is a pain to reproduce on all the 开发者_StackOverflowmethods. Something like hundreds of methods :(
This needs to be controlled in the view side. Don't you find it by yourself very annoying when you see on some site a button for which you don't have sufficient rights to press and thus get an intimidating error page when you do so?
Just render the button in the view side only when the user has the required role, else hide it altogether.
<h:commandButton value="Delete" action="#{bean.delete}"
rendered="#{request.isUserInRole('administrator')}" />
This is not sensitive to (CSRF) hacks as JSF checks the condition once again during apply request values phase.
As to using multiple conditions and repeating the same over and over in a single view, consider using <c:set>
to give it a short alias. You could even place it in the top of some master template so that it's available to all child templates.
<c:set var="isPowerUser" value="#{request.isUserInRole('manager') or request.isUserInRole('administrator')}" scope="request" />
...
<h:commandButton rendered="#{isPowerUser}" />
...
<h:commandButton rendered="#{isPowerUser}" />
You can shorten that by moving the logic to an utility method:
public class AuthorizationUtils {
public static boolean isUserInRoles(String[] roles) {
for (String role : roles) {
if (FacesContext........isUserInRole(role)) {
return true;
}
}
return false;
}
}
And then invoke it with:
if (AuthorizationUtils.isUserInRoles(new String[] {"administrator", "moderator"})) {
..
}
If you are using CDI, you can make an interceptor that handles the @RolesAllowed
annotation
@Mediterran81: So basically you are looking for bean-method based authorization solution...how are you instantiating your managed beans? You may like to introduce a simple XML format:-
<bean class="">
<method name="">
<role> xyz</role>
</method>
</bean>
Have this XML read by utility class and then only thing you would need to do is to call Utility's static method to determine if method is allowed to execute.
精彩评论