1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.acegisecurity.taglibs.authz;
16
17 import org.acegisecurity.acls.Acl;
18 import org.acegisecurity.acls.AclService;
19 import org.acegisecurity.acls.NotFoundException;
20 import org.acegisecurity.acls.Permission;
21 import org.acegisecurity.acls.domain.BasePermission;
22 import org.acegisecurity.acls.objectidentity.ObjectIdentity;
23 import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategy;
24 import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl;
25 import org.acegisecurity.acls.sid.Sid;
26 import org.acegisecurity.acls.sid.SidRetrievalStrategy;
27 import org.acegisecurity.acls.sid.SidRetrievalStrategyImpl;
28
29 import org.acegisecurity.context.SecurityContextHolder;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import org.springframework.context.ApplicationContext;
35
36 import org.springframework.web.context.support.WebApplicationContextUtils;
37 import org.springframework.web.util.ExpressionEvaluationUtils;
38
39 import java.util.HashSet;
40 import java.util.Map;
41 import java.util.Set;
42 import java.util.StringTokenizer;
43
44 import javax.servlet.ServletContext;
45 import javax.servlet.jsp.JspException;
46 import javax.servlet.jsp.PageContext;
47 import javax.servlet.jsp.tagext.Tag;
48 import javax.servlet.jsp.tagext.TagSupport;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class AccessControlListTag extends TagSupport {
66
67
68 protected static final Log logger = LogFactory.getLog(AccessControlListTag.class);
69
70
71
72 private AclService aclService;
73 private ApplicationContext applicationContext;
74 private Object domainObject;
75 private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy;
76 private SidRetrievalStrategy sidRetrievalStrategy;
77 private String hasPermission = "";
78
79
80
81 public int doStartTag() throws JspException {
82 initializeIfRequired();
83
84 if ((null == hasPermission) || "".equals(hasPermission)) {
85 return Tag.SKIP_BODY;
86 }
87
88 final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission,
89 pageContext);
90
91 Permission[] requiredPermissions = null;
92
93 try {
94 requiredPermissions = parsePermissionsString(evaledPermissionsString);
95 } catch (NumberFormatException nfe) {
96 throw new JspException(nfe);
97 }
98
99 Object resolvedDomainObject = null;
100
101 if (domainObject instanceof String) {
102 resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", (String) domainObject,
103 Object.class, pageContext);
104 } else {
105 resolvedDomainObject = domainObject;
106 }
107
108 if (resolvedDomainObject == null) {
109 if (logger.isDebugEnabled()) {
110 logger.debug("domainObject resolved to null, so including tag body");
111 }
112
113
114 return Tag.EVAL_BODY_INCLUDE;
115 }
116
117 if (SecurityContextHolder.getContext().getAuthentication() == null) {
118 if (logger.isDebugEnabled()) {
119 logger.debug(
120 "SecurityContextHolder did not return a non-null Authentication object, so skipping tag body");
121 }
122
123 return Tag.SKIP_BODY;
124 }
125
126 Sid[] sids = sidRetrievalStrategy.getSids(SecurityContextHolder.getContext().getAuthentication());
127 ObjectIdentity oid = objectIdentityRetrievalStrategy.getObjectIdentity(resolvedDomainObject);
128
129
130 try {
131 Acl acl = aclService.readAclById(oid, sids);
132
133 if (acl.isGranted(requiredPermissions, sids, false)) {
134 return Tag.EVAL_BODY_INCLUDE;
135 } else {
136 return Tag.SKIP_BODY;
137 }
138 } catch (NotFoundException nfe) {
139 return Tag.SKIP_BODY;
140 }
141 }
142
143
144
145
146
147
148
149
150
151 protected ApplicationContext getContext(PageContext pageContext) {
152 ServletContext servletContext = pageContext.getServletContext();
153
154 return WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
155 }
156
157 public Object getDomainObject() {
158 return domainObject;
159 }
160
161 public String getHasPermission() {
162 return hasPermission;
163 }
164
165 private void initializeIfRequired() throws JspException {
166 if (applicationContext == null) {
167 this.applicationContext = getContext(pageContext);
168
169 Map map = applicationContext.getBeansOfType(AclService.class);
170
171 if (map.size() != 1) {
172 throw new JspException(
173 "Found incorrect number of AclService instances in application context - you must have only have one!");
174 }
175
176 aclService = (AclService) map.values().iterator().next();
177
178 map = applicationContext.getBeansOfType(SidRetrievalStrategy.class);
179
180 if (map.size() == 0) {
181 sidRetrievalStrategy = new SidRetrievalStrategyImpl();
182 } else if (map.size() == 1) {
183 sidRetrievalStrategy = (SidRetrievalStrategy) map.values().iterator().next();
184 } else {
185 throw new JspException("Found incorrect number of SidRetrievalStrategy instances in application "
186 + "context - you must have only have one!");
187 }
188
189 map = applicationContext.getBeansOfType(ObjectIdentityRetrievalStrategy.class);
190
191 if (map.size() == 0) {
192 objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
193 } else if (map.size() == 1) {
194 objectIdentityRetrievalStrategy = (ObjectIdentityRetrievalStrategy) map.values().iterator().next();
195 } else {
196 throw new JspException("Found incorrect number of ObjectIdentityRetrievalStrategy instances in "
197 + "application context - you must have only have one!");
198 }
199 }
200 }
201
202 private Permission[] parsePermissionsString(String integersString)
203 throws NumberFormatException {
204 final Set permissions = new HashSet();
205 final StringTokenizer tokenizer;
206 tokenizer = new StringTokenizer(integersString, ",", false);
207
208 while (tokenizer.hasMoreTokens()) {
209 String integer = tokenizer.nextToken();
210 permissions.add(BasePermission.buildFromMask(new Integer(integer).intValue()));
211 }
212
213 return (Permission[]) permissions.toArray(new Permission[] {});
214 }
215
216 public void setDomainObject(Object domainObject) {
217 this.domainObject = domainObject;
218 }
219
220 public void setHasPermission(String hasPermission) {
221 this.hasPermission = hasPermission;
222 }
223 }