1 package org.appfuse.service; 2 3 import java.lang.reflect.Method ; 4 import java.util.HashSet ; 5 import java.util.Iterator ; 6 import java.util.Set ; 7 8 import org.acegisecurity.AccessDeniedException; 9 import org.acegisecurity.Authentication; 10 import org.acegisecurity.AuthenticationTrustResolver; 11 import org.acegisecurity.AuthenticationTrustResolverImpl; 12 import org.acegisecurity.GrantedAuthority; 13 import org.acegisecurity.context.SecurityContext; 14 import org.acegisecurity.context.SecurityContextHolder; 15 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; 16 import org.acegisecurity.providers.dao.UserCache; 17 import org.acegisecurity.userdetails.UserDetails; 18 import org.apache.commons.collections.CollectionUtils; 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.appfuse.Constants; 22 import org.appfuse.model.Role; 23 import org.appfuse.model.User; 24 import org.springframework.aop.AfterReturningAdvice; 25 import org.springframework.aop.MethodBeforeAdvice; 26 27 public class UserSecurityAdvice implements MethodBeforeAdvice, AfterReturningAdvice { 28 public final static String ACCESS_DENIED = "Access Denied: Only administrators are allowed to modify other users."; 29 protected final Log log = LogFactory.getLog(UserSecurityAdvice.class); 30 private UserCache userCache; 31 32 public void setUserCache(UserCache userCache) { 33 this.userCache = userCache; 34 } 35 36 40 public void before(Method method, Object [] args, Object target) throws Throwable { 41 SecurityContext ctx = SecurityContextHolder.getContext(); 42 43 if (ctx.getAuthentication() != null) { 44 Authentication auth = ctx.getAuthentication(); 45 boolean administrator = false; 46 GrantedAuthority[] roles = auth.getAuthorities(); 47 for (int i=0; i < roles.length; i++) { 48 if (roles[i].getAuthority().equals(Constants.ADMIN_ROLE)) { 49 administrator = true; 50 break; 51 } 52 } 53 54 User user = (User) args[0]; 55 String username = user.getUsername(); 56 57 String currentUser; 58 if (auth.getPrincipal() instanceof UserDetails) { 59 currentUser = ((UserDetails) auth.getPrincipal()).getUsername(); 60 } else { 61 currentUser = String.valueOf(auth.getPrincipal()); 62 } 63 64 if (username != null && !username.equals(currentUser)) { 65 AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl(); 66 boolean signupUser = resolver.isAnonymous(auth); 68 if (!signupUser) { 69 if (log.isDebugEnabled()) { 70 log.debug("Verifying that '" + currentUser + "' can modify '" + username + "'"); 71 } 72 if (!administrator) { 73 log.warn("Access Denied: '" + currentUser + "' tried to modify '" + username + "'!"); 74 throw new AccessDeniedException(ACCESS_DENIED); 75 } 76 } else { 77 if (log.isDebugEnabled()) { 78 log.debug("Registering new user '" + username + "'"); 79 } 80 } 81 } 82 83 else if (username != null && username.equalsIgnoreCase(currentUser) && !administrator) { 86 87 Set userRoles = new HashSet (); 89 if (user.getRoles() != null) { 90 for (Iterator it = user.getRoles().iterator(); it.hasNext();) { 91 Role role = (Role) it.next(); 92 userRoles.add(role.getName()); 93 } 94 } 95 96 Set authorizedRoles = new HashSet (); 98 for (int i=0; i < roles.length; i++) { 99 authorizedRoles.add(roles[i].getAuthority()); 100 } 101 102 if (!CollectionUtils.isEqualCollection(userRoles, authorizedRoles)) { 105 log.warn("Access Denied: '" + currentUser + "' tried to change their role(s)!"); 106 throw new AccessDeniedException(ACCESS_DENIED); 107 } 108 } 109 } 110 } 111 112 public void afterReturning(Object returnValue, Method method, Object [] args, Object target) 113 throws Throwable { 114 User user = (User) args[0]; 115 116 if (userCache != null && user.getVersion() != null) { 117 if (log.isDebugEnabled()) { 118 log.debug("Removing '" + user.getUsername() + "' from userCache"); 119 } 120 121 userCache.removeUserFromCache(user.getUsername()); 122 123 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 125 if (auth != null && auth.getPrincipal() instanceof UserDetails) { 126 User currentUser = (User) auth.getPrincipal(); 127 if (currentUser.getId().equals(user.getId())) { 128 if (!currentUser.getUsername().equalsIgnoreCase(user.getUsername())) { 129 if (log.isDebugEnabled()) { 132 log.debug("Removing '" + currentUser.getUsername() + "' from userCache"); 133 } 134 userCache.removeUserFromCache(currentUser.getUsername()); 135 } 136 auth = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()); 137 SecurityContextHolder.getContext().setAuthentication(auth); 138 } 139 } 140 } 141 } 142 } 143 | Popular Tags |