KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > appfuse > service > UserSecurityAdvice


1 package org.appfuse.service;
2
3 import java.lang.reflect.Method JavaDoc;
4 import java.util.HashSet JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.Set JavaDoc;
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 JavaDoc 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     /**
37      * Method to enforce security and only allow administrators to modify users. Regular
38      * users are allowed to modify themselves.
39      */

40     public void before(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc target) throws Throwable JavaDoc {
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 JavaDoc username = user.getUsername();
56
57             String JavaDoc 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                 // allow new users to signup - this is OK b/c Signup doesn't allow setting of roles
67
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             // fix for http://issues.appfuse.org/browse/APF-96
84
// don't allow users with "user" role to upgrade to "admin" role
85
else if (username != null && username.equalsIgnoreCase(currentUser) && !administrator) {
86
87                 // get the list of roles the user is trying add
88
Set JavaDoc userRoles = new HashSet JavaDoc();
89                 if (user.getRoles() != null) {
90                     for (Iterator JavaDoc it = user.getRoles().iterator(); it.hasNext();) {
91                         Role role = (Role) it.next();
92                         userRoles.add(role.getName());
93                     }
94                 }
95
96                 // get the list of roles the user currently has
97
Set JavaDoc authorizedRoles = new HashSet JavaDoc();
98                 for (int i=0; i < roles.length; i++) {
99                     authorizedRoles.add(roles[i].getAuthority());
100                 }
101
102                 // if they don't match - access denied
103
// users aren't allowed to change their roles
104
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 JavaDoc returnValue, Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc target)
113     throws Throwable JavaDoc {
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             // reset the authentication object if current user
124
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                         // The name of the current user changed, so the previous flush won't have done anything.
130
// Flush the old name, too.
131
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