JSF action permission

2007-02-15
2013-05-08
  • André Pestana
    André Pestana
    2007-02-15

    Hello,

    I'm wondering how could we secure JSF actions instead of through URL and got the conclusion:

    we can manage JSF security by:

    - URL (it's already done)
    - Tag (it's already done)
    - JSF-EL execution. Example: permission for #{ MyBean.delete }
    - faces-config.xml mapping. Example: permission for "show_salary" mapping.
      <navigation-case>
       <from-outcome>show_salary</from-outcome>
       <to-view-id>/pages/salary.jsp</to-view-id>
       <redirect/>
      </navigation-case>

    URL
    If you manage JSF security by URL you're restricted to permit a group of action, not really distinct actions.

    Tag
    It's possible to manage security by introducing tags around all pages of your app but it's too intrusive and demands too much work to do it. Nevertheless it's good when you need to hid something.

    faces-config.xml mapping
    It'd be good if we could deny or permit these mappings only to prevent the user to access (SEE) some denied info but it's not suficient because a method could be executed before calling the mapping.

    JSF-EL execution
    This kind of permission is the way we could deny bean methods to be executed.

    I've googled and found a way to intercept actionMethod's (JSF-EL) and actionName's (mappings) via NavigationHandler. I did a test:

    [faces-config.xml]
    <application>
      <navigation-handler>br.com.pestana.MyNavigationHandler</navigation-handler>
    </application>

    [MyNavigationHandler.java]
    public class MyNavigationHandler extends NavigationHandler {
        private NavigationHandler handler;
        public MyNavigationHandler (NavigationHandler handler) {
            super();
            this.handler = handler;
        }
        public void handleNavigation(FacesContext fc, String actionMethod, String actionName) {
            // TODO Auto-generated method stub
            System.out.println("\n\n\nactionName   = "+actionName);
            System.out.println("actionMethod = "+actionMethod+"\n\n\n");
            handler.handleNavigation(fc, actionMethod, actionName);
        }
    }

    I think we must create these 2 permission types to improve JSF security in new jguard release. I know it's a little intrusive but I think it's good way to manage it.

    Has someone got a better solution for it?

    André

     
    • André Pestana
      André Pestana
      2007-02-16

      Hi, again!

      There's another help for JSF developers that could be done. Today, authorize tags are oriented to URL. Example:

      <jguard:authorized uri="/SwitchToModule?prefix=/admin&amp;page=/Administration.do">
        Only for administrators...
      </jguard:authorized>

      If I could give names for "modules" like above, it could be better for JSF:

      <jguard:authorized module="userAdministration">
        Only for administrators...
      </jguard:authorized>

      I don't know if uri can be changed by anything I want but it seems to be more clear for permission managers to understand that it's a module and not a URI.

      It's just one more suggestion.

      Any suggestions?

      André

       
      • Charles Lescot
        Charles Lescot
        2008-03-25

        Hi,
        you're right that some tags are shipped for URL.but other more general tags permits to declare any Permission subclasses like JSFPermission.
        the only drawback is the long length of the declaration.
        for this purpose, you can use the tag described here:
        http://jguard.sourceforge.net/mvnsite/docbook/en_jGuard_reference.html#d108e3764

        exceprt:
        <jguard:hasPermission className="java.io.FilePermission" name="/home/myDirectory" actions="read">
        content displayed only if the user has got the specified permission
        </jguard:hasPermission>

        hope it helps,

        charles.

         
    • Charles Lescot
      Charles Lescot
      2007-02-19

      Hi André,
      about JSF-EL variables:
      to provide jGuard variable in JSF-EL scope, we need to implement the Propertyresolver and VariableResolver:
      http://java.sun.com/javaee/javaserverfaces/1.0/docs/api/javax/faces/el/PropertyResolver.html
      http://java.sun.com/javaee/javaserverfaces/1.0/docs/api/javax/faces/el/VariableResolver.html

      about your solution:
      i think that's a good way to fit closely to the JSF model.
      to enable it, we should modify the AccessFilter to specify or not (not in this case), if we want it creates automatically based on the url an URLPermission and checks it.
      in this case, we should do in the Navigationhandler:
      create a JSF-related Permission based on actioName and ActionMethod, and calls the AccessController.checkPermission(myJSFMethodPermission);
      if the user has not access to the method, an accessControlException will be thrown, and catched by the AccessFilter which will handle it in a clean way.
      maybe we can name the permissions you refer as JSFMethodPermission, and a JSFActionPermission.
      the first one will allow only user to execute a method of a specified action.
      the other one will allow the user to execute all the methods of the JSF action.

      another guy has used a PhaseListener approach here:
      http://jdj.sys-con.com/read/250254.htm

      the Navigationhandler approach you propose seems simpler and better.

      what is your feedback on the PhaseListener approach?

      another topic:
      about using maven, have you had some difficulties?
      => i need to put create in the pom.xml some variables referencing java4_home and java5_home instead of my path..

      we need also to create the jguard-jsf-example in the svn repository, bound to the jguard liefecycle (the amin release will contains the jsf example).

      cheers,

      Charles.

       
    • Charles Lescot
      Charles Lescot
      2007-02-19

      another thing about tag:
      since jguard 1.0.0, a new tag has been provided permitting to protect content based on any permission subclasses, including the future JSF permissions:

      <jguard:hasPermission class="java.io.FilePermission" name="/home/myDirectory" actions="read">
      content displayed only if the user has got the specified permission
      </jguard:hasPermission>

      cheers,

      Charles.

       
    • André Pestana
      André Pestana
      2008-03-11

      Hello!

      Wow... this thread has more than one year. :)

      I've found an article that can help us with this issue:
      http://blogs.sun.com/enterprisetechtips/entry/improving_jsf_security_configuration_with

      Coincidentally it's written by a brazilian guy ;)

      Charles, what do you think? Could we implement some of these things in jGuard?

      Cheers,

      André

       
      • Charles Lescot
        Charles Lescot
        2008-03-26

        Hi,
        the solution pointed is a good example.
        we also used a phaselistener(called accesslistener) in jguard, but not yet a navigationHandler.
        we should also provide some annnotation to avoid use in method some check block code like AccessController.checkPermission(...).

        note that our AccessListener in the afterPahse method calls the PolicyEnforcementPoint process method:
        it implies a call after that to a JSFauthenticationbindings if authentication is required, with a call to a current *NavigationHandler* (in the redirect method used by the authenticationSucceed or authenticationFailed methods), or a call to JSFauthorizationbindings which also call the navigationHandler in its accesDenied method.
        NavigationHandler nh = facesContext.getApplication().getNavigationHandler();

        note that the JSFauthorizationBindings grab the requested permission with this code:
        FacesContext.getCurrentInstance().getViewRoot().getViewId.

        so, we use the current NavigationHandler.
        do we need to implements ours?

        hope it helps,

        charles.

         
    • Charles Lescot
      Charles Lescot
      2008-03-25

      Hi,
      the JSFPermission already exists and embeds in its 'name' attribute the viewId(actionName mapping) present in the faces-config.xml configuraiton file.
      jGuard already provides a PhaseListener to use this approach.
      maybe a more complete solution would be to provide a navigationhandler impelmentation too like described?
      do you think we should enhance the JSFPermission (with the actions attribute) to include method name optionally?

      cheers,

      Charles.