bridging the portals via aop
Tue, Sep 18, 2007
I’ve put in place the last part of the GSK jigsaw, adding an AOP bridge between /portal-shibb and /portal. The problem was that a user, if they login to Sakai via the GSK, come in via the /portal-shibb route. However, when they logout, they leave via the /portal route. This means that the GSK portal doesn’t know they’ve logged out and their Pod is still active in the system.
The way round this is to use AOP. I could have used the Sakai event API but I could find neither the API nor any documentation to explain how it works and how to use it. So I used AOP instead, as I’d been working on it and relished the chance to use it for real.
The key was the Spring BeanPostProcessor interface. This is a class that Spring will call every time a bean is loaded from a config file. In Sakai’s case, this usually means a component.xml in the /components directory. Spring will let the processor know when it’s loaded a bean but before it’s called the bean’s init method and it will also let the processor know when it has loaded the bean AND called its init method. It’s the second call that we’re interested in.
All you have to do to inject a BeanPostProcessor implementatio is declare it in a config file that Spring will load. In this case, I declared it in:
<bean class=“org.guanxi.sp.sakai.pod.impl.aop.GuanxiAOPProxy” />
Spring will then call GuanxiAOPProxy.postProcessBeforeInitialization(), which we don’t care about and GuanxiAOPProxy.postProcessAfterInitialization(), which we do.
The AOP proxy, GuanxiAOPProxy, detects when org.sakaiproject.event.api.UsageSessionService has been loaded and initialised by Spring and creates a point cut for the logout() method with an advice of org.guanxi.sp.sakai.pod.impl.aop.GuanxiAOPInterceptor. It then returns an AOP proxy that encapsulates this behaviour.
What happens then, is when the user logs out of the main portal, UsageSessionService.logout() is called by Sakai but as it’s not really UsageSessionService, rather, it’s an AOP proxy, GuanxiAOPInterceptor is called instead. This class does it’s work of deleting the user’s Pod and then delegating to the original UsageSessionService.logout() method call.
So there we have it, GSK + AOP = SSO!
Some interesting resources: