Who did you say you were?
Posted by danielmeyer on October 16, 2008
Sometimes you want authentication — you don’t want to let a connection in to your system unless it supplies the right credentials. Other times, you just want identification — for instance, you might want to remember who it was that initiated a request.
One example of this distinction is when you’re dealing with JMS queues. The process that puts a message in a queue may have been involved in authenticating the user… but the process that takes that message out of the queue to process may not have been. That receiving process needs a way to identify the user that placed the message in the queue.
The first part of the solution is to pass the userId along with the JMS message, to the queue. You can do this by setting a String property on the JMS Message.
Before we can use LDAP to look up information about this user, though, we need to populate the Spring security context with this userId. (Spring does support setting the SecurityContextHolder contents directly.) So that the domain-level developers don’t have to worry about this, we can use AOP around-advice, like this:
public Object doPopulateSecurityContext(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Message message = (Message) proceedingJoinPoint.getArgs()[0];
String userId = message.getStringProperty("userId");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userId, "");
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(authenticationToken);
SecurityContextHolder.setContext(context);
Object retVal = proceedingJoinPoint.proceed();
SecurityContextHolder.clearContext();
return retVal;
}
This populates the information about the current user so that the MessageListener can look up things in LDAP based on that.