AOP wonderland
How cool it is to have your code working with all your aspects (thanks Nanning) and interceptors!Now my RMI framework has been enhanced with some security interceptors. The client one login the user using JAAS and serialize the javax.security.auth.Subject while the server one fetch it and run the server-side implementation of the RMI call under this javax.security.auth.Subject. I did this with an interceptor putting the javax.security.auth.Subject object in a java.lang.ThreadLocal so that my interceptor has only to be instanciated once.As I added a static method on my interceptors in order to retreive the javax.security.auth.Subject of the current thread, each service backend can do authorization (yep, I meant authorization and not authentication). Of course the whole application is written using Jini services and smart proxies so I can even use this security information within the smart proxy.Writing a security auditing interceptor that will log who did what and when is then as simple as that:
import com.kalixia.services.ServiceBackend;
import com.tirsen.nanning.Invocation;
import com.tirsen.nanning.MethodInterceptor;
import com.tirsen.nanning.definition.SingletonInterceptor;
import org.apache.log4j.Logger;
import java.security.Principal;/**
* Server-side security audit interceptor.
* This interceptor expects a method call on a {@link ServiceBackend}.
* @author Jerome Bernard (jerome.bernard@xtremejava.com)
*/
public class SecurityAuditInterceptor implements MethodInterceptor, SingletonInterceptor {
private static final Logger log = Logger.getLogger(SecurityAuditInterceptor.class); public Object invoke(final Invocation invocation) throws Throwable {
if (invocation.getProxy() instanceof ServiceBackend &&
SecurityInterceptor.getSubject() != null &&
SecurityInterceptor.getSubject().getPrincipals() != null) {
ServiceBackend service = (ServiceBackend) invocation.getProxy();
Principal principal = (Principal) SecurityInterceptor.getSubject().getPrincipals().iterator().next();
StringBuffer auditLog = new StringBuffer();
auditLog.append("User: ").append(principal.getName());
auditLog.append(" used service ").append(service.getName());
auditLog.append(" at ").append(System.currentTimeMillis()).append(".");
log.info(auditLog.toString());
}
return invocation.invokeNext();
}
}