ACEGI JSF Components hit the stores

Acegi Security Framework’s mission statement is; “To provide comprehensive security services for The Spring Framework” as stated in acegisecurity.org. In our project we are using JSF-Spring-Hibernate and lately for the security issues, we made the obvious choice Acegi Framework. Acegi has very nice features like securing HTTP Requests, spring method calls and domain object instance security. My first encounter with Acegi was a presentation given by Kenan Sevindik, he showed a demo featuring http requests, spring method calls, testing and securing components on a page by acegi’s jsp tags.

Acegi uses a structure like this when securing components on a page;

<authz:authorize ifAllGranted=”ROLE_SUPERVISOR”>
    Components that are only visible to the users that satisfy the requirements here…
</authz:authorize>

This tag library has the following attributes ifAllGranted, ifAnyGranted and ifNotGranted, what it does is controlling the components within the tag body and does not render if the user’s role does not satisy the requirements.

And another one to display user info;

<authz:authentication operation=”username”/>

Although these tags may work with JSF, we need pure jsf components for acegi in our project (for value binding and etc.) that will play nicely with JSF lifecycle so I’ve implemented “acegi-jsf” custom components. Instead of Acegi’s authz taglib, the name is acegijsf, the tag names and attributes are the same. More will come in the next release(hopefully).

ACEGI-JSF AUTHORIZATION
<acegijsf:authorize ifAllGranted=”ROLE_SUPERVISOR,ROLE_ADMIN”>
     Components that are only visible to the users that satisfy the requirements here…
</acegijsf:authorize>

The attribute names are same both in jsp tag and the jsf component. You just give a role list seperated with a comma(Whitespaces omitted). All of these attributes can be binded to a value using EL.

ifAllGranted = User must be in all of the roles
ifAnyGranted = User must be in any of the roles
ifNotGranted = None of the roles must be granted for the user

This component does not render the secured children components if the user does not satisfy the granting requirements given with the attributes.

ACEGI-JSF AUTHENTICATION
<acegijsf:authentication operation=”username”/>

This component does what the acegi’ authentication tag does and outputs user info.

HOW TO USE
You just need to add the following taglib in order to use the acegi-jsf components in your pages;

You also need to define the “SecurityContextHolderAwareRequestFilter” to your filter chain. (This dependency will be fixed in version 1.2)

<%@taglib uri=”http://sourceforge.net/projects/jsf-comp/acegijsf&#8221; prefix=”acegijsf”%>

SECURING STATIC HTML
This component library is designed to secure the jsf components. However controlling static html is also possible using f:verbatim. Html code must be surrounded by an f:verbatim tag. Important thing is “not to add the jsf components to the body of the verbatim tag”. Due to the content-interweaving problem of jsf and jsp, this will cause errors. Good news is that, it is fixed in JSF 1.2.

DOWNLOAD
You can find both of the distribution and the source of the component library at jsf-comp. As I mentioned in my previous entry, it is an alternative sandbox of myfaces. In addition I’ve created an example web application demonstrating the integration of jsf, spring, acegi and usage of the acegi-jsf components.

About these ads

39 Responses to ACEGI JSF Components hit the stores

  1. Thomas says:

    Great idea!
    I’ll give it a try very soon!
    Thanks very much

  2. Thomas says:

    Hi,

    I would like to use your component with facelets.
    I tried first to use it with JSP but I could not have it working.
    Would you have a working sample application to show how to integrate it?

    I also have question : what is the reason why the JSP tag library can not be used with JSF?
    I am new to JSF and I would appreciate some more info about that.

    Thanks,

    Thomas

    PS : I post this both in Myfaces list and in your blog so that you can answer where you think it is more suitable.

  3. Sandip says:

    Hi,

    Do you have a sample application for what you described above?

    Thanks & Regards,

    Sandip

  4. Cagatay says:

    Hi, not for now, but soon there will be.

  5. Thomas says:

    I have modified your Authentication tag with some code from acegi to get other information than the username :

    public class Authentication extends UIComponentBase {
    	public static final String COMPONENT_TYPE = "net.sf.jsfcomp.acegijsf.Authentication";
    	public static final String COMPONENT_FAMILY ="net.sf.jsfcomp.acegijsf";
    
    	public Authentication() {
    		setRendererType(null);
    	}
    
    	public void encodeBegin(FacesContext context) throws IOException {
            ResponseWriter writer = context.getResponseWriter();
    		String operation = (String) getAttributes().get("operation");
            org.acegisecurity.Authentication auth =
                SecurityContextHolder.getContext().getAuthentication();
    
            if (auth.getPrincipal() != null){
                if (auth.getPrincipal() instanceof UserDetails){
                    writer.write(invokeOperation(auth.getPrincipal(), operation));
                }
                else {
                    writer.write(auth.getPrincipal().toString());
                }
            }
            else{
                writer.write("Unknown");
            }
    	}
    
    	public String getFamily() {
    		return COMPONENT_FAMILY;
    	}
    
        protected String invokeOperation(Object obj, String operation){
            Class clazz = obj.getClass();
            String methodToInvoke = operation;
            StringBuffer methodName = new StringBuffer();
            methodName.append("get");
            methodName.append(methodToInvoke.substring(0, 1).toUpperCase());
            methodName.append(methodToInvoke.substring(1));
    
            Method method = null;
            Object retVal = "";
    
            try {
                method = clazz.getMethod(methodName.toString(), (Class[]) null);
                retVal = method.invoke(obj, (Object[]) null);
            }
            catch (Exception e) {}
    
            return retVal.toString();
        }
    }
    
  6. sandipsahoo says:

    Hi Cagatay,

    I have downloaded the sample jsf page. I need one sample application how you are implementing the acegi&Jsf components.

    Can you plz send me that?

    Thanks & Regards,
    Sandip

  7. Duncan Mills says:

    I can’t help feeling that this is not the best approach – I’ve done a similar thing with J2EE container security but the tack we’ve taken there is to extend the Faces expression language rather than create a whole new set of components.
    Thus you can apply security conditions to *any* component or container without having to encapsulate them in a security specific component
    That project is also on sourceforce (http://jsf-security.sourceforge.net/).
    The mechanism there is fully pluggable – I’d love to put an Acegi adapter in – if you’re interested let me know

  8. Cagatay says:

    Hi, this component series are also pluggable if acegi is employed, it does not depend on the J2EE container, acegi wraps the security, components just use the request isUserInRole kinda methods, no acegi specific. The main advantage is the independency from the J2EE container and securing several components under one tag, without playing with the rendered or disabled propertied of each one. This is the approach that Acegi Development Team has followed.

  9. Duncan Mills says:

    I absolutley agree that you don’t want to depend on the Container – I’ll not contest that.
    My point is that I think that creating specific security components is perhaps not the best way. Using an extended expression language you get all of the benefits of the components and more – for instance – it’s not just a matter of hiding a component when a user is not in a particular role, how about simply making it read-only in that case, or changing some other attribute, or even combining conditional processing e.g.

    if value of “status” = “new” and role = “customer” then component is editable else component is read only.

    Yes you can do all of these things with a component based approach,but it gets messy. It can be much more consise and simpler in the page with an EL based syntax.

  10. Cagatay says:

    Hi Duncan, I think both ways have pros and cons. I really like the resolver approach, it really can provide flexibility but if a role is changed one must go through all the EL expressions and change them and it is likely to occur.On the other hand, the component approach provides a more centralized solution.The possible disadvantage of the component approach will be the flexibility issue however it is easy to provide features like just disable, which I will implement in the new release.At this point I dont agree that things will get messy because it is all hidden from the component’s user.Since both have pros and cons, they should be applied according to the requirements.

  11. Michael says:

    What about the acl tag?

  12. Guoliang Cao says:

    I tried this in my jsp page:

    1


    2


    3

    and all of 1,2 and 3 show up in response. What can be wrong?

  13. Guoliang Cao says:

    I added System.out.println() to Authorize.encodeChildren() and redeployed my web application but nothing is written to console. I don’t know much about JSF tags but this probably is the reason why those tags don’t work on my machine.

  14. Cagatay says:

    The current version is only applicable on jsf components so it will not try secure the pure html. In the next release of the components, I am planning to add this feature.Maybe you should try outputText components with values “1”,”2″,”3″. If that does not also work then you should check your acegi configuration.

  15. Balaji says:

    hi,

    I want to integrate ACEGI sec with myfaces/JSF. Can anyone give me pointer where to look for tutorial/guidlines?

    Some working example will be better to have kick start.

    Thanks in advance.

    –Balaji
    PS: I have tried downloading acegijsfsamplepage.jar, but seems there is some problem with file. The dowloaded file size is 536 B.

  16. Cagatay says:

    This should be a nice starting point, http://www.jroller.com/page/fairTrade

  17. Michael Schulz says:

    I am facing the same problem as Balaji. The file acegijsfsamplepage.jar does not contain any content. Even the file on sourceforge that should contain the sources is empty. Maybe some problem with the build?
    Best regards, Michael

  18. Cagatay says:

    I’ve just made a new release of version 1.1.1 at sourceforge. Also a sample web application will be released soon.

  19. Cagatay Civici says:

    Due to an erronous release and a bug 1.1.1 is canceled. All of these are fixed and released in 1.1.2.

  20. dave says:

    Hi Cagatay,
    I was wondering if there is any chance of making a taglib definition to make this work in facelets? https://facelets.dev.java.net/

    Best wishes, Dave

  21. Cagatay says:

    Hi Dave, yes of course, I’ll create and link the file to the entry.

  22. Petros says:

    Hi,

    here is the taglib file for using with facelets:

    acegijsf.taglib.xml:
    < ?xml version="1.0"?>
    < !DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd">

    http://sourceforge.net/projects/jsf-comp/acegijsf

    authorize

    net.sf.jsfcomp.acegijsf.Authorize


    authentication

    net.sf.jsfcomp.acegijsf.Authentication

  23. Michael Kötter says:

    From looking at the source, I figure the components use the HttpServletRequest.isUserInRole() calls – plain servlet security, that is.
    No offense, but what’s the point in calling this “Acegi”? I think it won’t even work with Acegi out of the box unless you employ the “SecurityContextHolderAwareRequestFilter”… maybe you should mention that ;)

  24. jolestar says:

    does it work well with MyFaces?

  25. Cagatay says:

    Michael, you have a point. The older versions use container security info which was wrapped by Acegi. The new version I’ll be releasing soon is based on pure Acegi. And jolestar, yes it is compatible with myfaces.

  26. Chris says:

    i’m trying to use acegi with facelets but i just can’t get the taglib to work. On

    i receive a nullpointer-exception, and consequently there’s no way to figure out the GrantedAuthorities (i’m using the above mentioned facelet-taglib).

    when using a jsp-page everything works fine, so i don’t think the problem is with the acegi-configuration but rather with the facelets-integration.

    Does anybody happen to have a working sample application for acegi and facelets?

  27. Cagatay says:

    Hi Chris, is SecurityContextHolderAwareRequestFilter defined in your filterchain acegi configuration. The new version of acegi-jsf(1.2) will not need this filter to be defined but older versions does.

  28. Chris says:

    Hi Cagatay,
    that fixed it. Thanks a lot!

  29. Berserksangr says:

    Cagatay,

    When a new version of the ACEGI component will be relased?

    Thank you for your hard work.

  30. Cagatay says:

    Hi, “in a month” hopefully, I just need some more ideas and free time:)

  31. Matt Raible says:

    Is this component available in a Maven 2 repo?

  32. Cagatay says:

    no, it’s not

  33. diego says:

    are the security EL extensions for this component available yet?
    I mean #{securityContext.authType} etc…

    thanks

  34. Kiran Sagi says:

    The acegijsf components dont seem to work if embedded inside the tomahawk datatable. I also tried to embed them inside the exadel tabbed panel. They dont seem to work.

    I need to hide some columns in the datatable based on the roles….

    Is there any resolution for this???

  35. qding says:

    I use appfuse/JSF, to which the acegijsf tag is integrated. It works when I do this in my jsf page:

    Login as

    username is the property of the user object. In the User object, a method
    getFullName() is defined to return user’s first_name + ” ” + last_name.

    When I do

    , I do not get anything out.

    Username in my project is user’s login id, we don’t want to display it.
    I want to display user’s full name. How can I output the full name instead of username from user object using acegijsf tag? How to call a method on the user object?

  36. Matt says:

    How does this work with a JSF-Login Form?

  37. DamionKutaeff says:

    Hello everybody, my name is Damion, and I’m glad to join your conmunity,
    and wish to assit as far as possible.

  38. Q says:

    Does Acegi-JSF support ACL function for authz:acl tag ?

  39. Anonymous says:

    Hi,

    I am trying to authenticate user, if login fails the user should be on same page i.e. in login.xhtml.

    If login fails, the query return me nothing,role etc etc nothing.
    Can anybody tell me, how can I check that here in xhtml file?

    Welcome,

Follow

Get every new post delivered to your Inbox.

Join 108 other followers

%d bloggers like this: