Announcement Announcement Module
No announcement yet.
JBoss SSO + Acegi issue Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • JBoss SSO + Acegi issue

    Hello all,

    Here is my business/technical need. I need to be able to take advantage of JBoss SSO and clustering. I would also like to take advantage of Acegi. As far as I know, the only way to do both is to use the JBoss Acegi adapter. I am using that, and my simple example works.

    My Problem:
    The simple example has Acegi, Acegi-jboss and Spring in the jboss/mysetup/lib dir (nothing in WEB-INF/lib). This works fine and all is well.

    However in real life, I also use Spring in my business layer. This layer introduces a zillion other IOC dependencies, and I'd like these guys versioned with my application and not shared across everyone in jboss/mysetup/lib.

    If I keep everything out of jboss/mysetup/lib and instead keep everything in WEB-INF/lib it works...for the first application. The application that contains the login form has no trouble authenticating. However the other applications that are benefitting from JBoss SSO now have trouble because the JbossIntegrationFilter in App2 is no longer works. I assume this is because of classloader issues and the App2 JbossIntegrationFilter not being able to understand objects generated by App1 (the main login app).

    This puts me in kind of a bind. Either forget about versioning my business layer libs (which I don't like). Or not use JBoss SSO (which I can't do).

    I tried to meet in the middle. Only put the acegi* stuff in jboss/mysetup/lib. However they reference a Spring event class, and that pulls in the whole thing. I tried having Spring in both jboss/mysetup/lib and WEB-INF/lib. This causes a problem with Spring's ApplicationContext.

    11:47:08,565 ERROR [[/main]] Exception sending context initialized event to listener instance of class net.sf.acegisecurity.ui.session.HttpSessionEventPublisher
    java.lang.IllegalStateException: Root context attribute is not of type WebApplicationContext: display name [Root WebApplicationContext]; startup date [Wed Aug 31 11:47:07 PDT 2005]; root of context hierarchy; config locations [/WEB-INF/applicationContext-acegi-security.xml]
    	at net.sf.acegisecurity.ui.session.HttpSessionEventPublisher.contextInitialized(
    My guess here is that Spring tries to share its context, or have a single common context and manage sharing internally. This doesn't seem to work well if your context already exists but isn't of an object your classloader understands.

    Could someone with greater Acegi + Spring experience help me out?


  • #2
    I've done a bit more digging and am starting to see why this isn't working and why it can never work given Acegi's current functionality.

    Basically the problem is, how to give a single (JBoss) authenticated Acegi context to all Acegi enabled webapps on this machine (and those participating in the cluster).

    The non-SSO scenario works fine, and it operates by using a JBoss login class and filter. The login class performs the authentication, populates an Acegi Authentication subclass and puts it in a JNDI location for the filter. The filter then reads from this location and all is well.

    The problem seems to be that this context is only scoped to the relevant request, for this webapp. As it probably should be. I don't know how you'd be able to extend this same mechanism to a global shared JNDI in a mutli-user, multi-request, multi-webapp system.

    I guess that instead of storing an Authentication object in JNDI, both login module and filter could interact with an Acegi SSO service located via JNDI. This service doesn't exist yet, but doesn't sound too hard to write. It would basically provide a mechanism for the login module to say, here's an authenticated user with the following granted authorities. A new SSO filter could then ask for this information from the service when a request comes in. Of course, in order for this to work the SSO filter would need a way of getting your container authenticated username so it has a key to send to this hypothetical SSO service.

    Since I'm only interested in HTTP projects and JBoss has already authenticated me (with Acegi help) and populated my request.getRemoteUser() Principle, one could use that. If I'm willing to do that, it would be nice if the Servlet spec would provide a getRoles() method. With an appropriate user + roles combination I could write my own Acegi AuthenticationProvider pretty easily. Unfortunately the Servlet spec only provides isUserInRole() functionality. Not the interface that Acegi needs.

    However, Acegi has seen this problem before with CAS. CAS only provides Acegi with an authenticated user, but not authorized roles. It's up to the Provider to get role information its self. So I could write an HTTPContextProvider that reads the pre-authorized user from the web context and was supplied some form of DAO for getting role information. Then my Acegi SSO solution would be as good as the JBoss SSO solution for providing a valid authenticated user. It would also follow the same semantics JBoss SSO has to boot.

    These all seem to be things I could do, and the HTTPContextProvider seems like the simplest approach. Before I go and write one, I'd like a little validation from someone in the know that this might actually work. And this being a security framework, work correctly.


    PS: And before someone asks, why not just use CAS. I haven't discounted CAS, but there are a lot of things that are attractive about JBoss SSO and clustering. I'd like to be able to have a choice between the two and use Acegi either way.


    • #3
      Does anyone know if Acegi is planning on adding support for getting principal information form the web context and role info from a configured DAO?

      I'd like an app server to provide authentication (published via getRemoteUser() ) and Acegi to provide the authorization.



      • #4
        Sounds like you have a good grasp on what is going on, Jim. The approaches you described should work. But seriously, consider CAS as it's a great solution. It's also cross-platform (ie your .Net, ASP, PHP, Apache etc servers can also coexist with each other in the same SSO environment).