package com.andypemberton.spring.mvc.portlet.security.aspect; import java.lang.reflect.Method; import java.util.Arrays; import javax.annotation.security.DenyAll; import javax.annotation.security.PermitAll; import javax.annotation.security.RolesAllowed; import javax.portlet.PortletRequest; import javax.portlet.PortletSecurityException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; /** * An AspectJ aspect that checks JSR250 security annotations (PermitAll, DenyAll, RolesAllowed) * against annotation-driven Spring Portlet MVC controllers. * * @author Andy Pemberton * */ @Aspect public class SpringJSR250SecurityAspect { @Pointcut("execution(java.lang.reflect.Method org.springframework.web.portlet.mvc.annotation..*.resolveHandlerMethod(..)) && args(request,..)") public void resolveHandlerMethodCall(PortletRequest request) { } @AfterReturning(pointcut = "resolveHandlerMethodCall(request)", returning = "method") public void applyAuthorization(JoinPoint joinPoint, Method method, PortletRequest request) throws PortletSecurityException { if (method != null) { PermitAll permitAll = method.getAnnotation(PermitAll.class); DenyAll denyAll = method.getAnnotation(DenyAll.class); RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class); if (permitAll != null && denyAll != null) { throw new IllegalStateException(method.toString() + " marked with both DenyAll and PermitAll."); } else if (denyAll != null) { throw new PortletSecurityException("Cannot access method: " + method.toString() + "; it is secured with DenyAll."); } else if (rolesAllowed != null) { boolean authorized = false; for (String role : rolesAllowed.value()) { if (request.isUserInRole(role)) { authorized = true; break; } } if (!authorized) { throw new PortletSecurityException("Cannot access: " + method.toString() + "; it is secured with RolesAllowed and the current user is not in the list of allowed roles: " + Arrays.toString(rolesAllowed.value())); } } } } }