1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.security;
15
16 import java.io.IOException;
17 import java.util.HashSet;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.eclipse.jetty.http.PathMap;
22 import org.eclipse.jetty.http.security.Constraint;
23 import org.eclipse.jetty.server.Connector;
24 import org.eclipse.jetty.server.HttpConnection;
25 import org.eclipse.jetty.server.Request;
26 import org.eclipse.jetty.server.Response;
27 import org.eclipse.jetty.server.UserIdentity;
28 import org.eclipse.jetty.util.StringMap;
29
30
31
32
33
34
35
36
37 public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware
38 {
39 private ConstraintMapping[] _constraintMappings;
40 private Set<String> _roles;
41 private PathMap _constraintMap = new PathMap();
42 private boolean _strict = true;
43
44
45
46
47
48
49 public boolean isStrict()
50 {
51 return _strict;
52 }
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public void setStrict(boolean strict)
69 {
70 _strict = strict;
71 }
72
73
74
75
76
77 public ConstraintMapping[] getConstraintMappings()
78 {
79 return _constraintMappings;
80 }
81
82
83 public Set<String> getRoles()
84 {
85 return _roles;
86 }
87
88
89
90
91
92
93
94
95
96
97 public void setConstraintMappings(ConstraintMapping[] constraintMappings)
98 {
99 setConstraintMappings(constraintMappings,null);
100 }
101
102
103
104
105
106
107
108
109
110
111 public void setConstraintMappings(ConstraintMapping[] constraintMappings, Set<String> roles)
112 {
113 if (isStarted())
114 throw new IllegalStateException("Started");
115 _constraintMappings = constraintMappings;
116
117 if (roles==null)
118 {
119 roles = new HashSet<String>();
120 for (ConstraintMapping cm : constraintMappings)
121 {
122 String[] cmr = cm.getConstraint().getRoles();
123 if (cmr!=null)
124 {
125 for (String r : cmr)
126 if (!"*".equals(r))
127 roles.add(r);
128 }
129 }
130 }
131
132 this._roles = roles;
133
134 }
135
136
137
138
139
140 @Override
141 protected void doStart() throws Exception
142 {
143 _constraintMap.clear();
144 if (_constraintMappings!=null)
145 {
146 for (ConstraintMapping mapping : _constraintMappings)
147 {
148 Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec());
149 if (mappings == null)
150 {
151 mappings = new StringMap();
152 _constraintMap.put(mapping.getPathSpec(),mappings);
153 }
154 RoleInfo allMethodsRoleInfo = mappings.get(null);
155 if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden())
156 {
157 continue;
158 }
159 String httpMethod = mapping.getMethod();
160 RoleInfo roleInfo = mappings.get(httpMethod);
161 if (roleInfo == null)
162 {
163 roleInfo = new RoleInfo();
164 mappings.put(httpMethod,roleInfo);
165 if (allMethodsRoleInfo != null)
166 {
167 roleInfo.combine(allMethodsRoleInfo);
168 }
169 }
170 if (roleInfo.isForbidden())
171 {
172 continue;
173 }
174 Constraint constraint = mapping.getConstraint();
175 boolean forbidden = constraint.isForbidden();
176 roleInfo.setForbidden(forbidden);
177 if (forbidden)
178 {
179 if (httpMethod == null)
180 {
181 mappings.clear();
182 mappings.put(null,roleInfo);
183 }
184 }
185 else
186 {
187 UserDataConstraint userDataConstraint = UserDataConstraint.get(constraint.getDataConstraint());
188 roleInfo.setUserDataConstraint(userDataConstraint);
189
190 boolean checked = constraint.getAuthenticate();
191 roleInfo.setChecked(checked);
192 if (roleInfo.isChecked())
193 {
194 if (constraint.isAnyRole())
195 {
196 if (_strict)
197 {
198
199 for (String role : _roles)
200 roleInfo.addRole(role);
201 }
202 else
203
204 roleInfo.setAnyRole(true);
205 }
206 else
207 {
208 String[] newRoles = constraint.getRoles();
209 for (String role : newRoles)
210 {
211 if (_strict &&!_roles.contains(role))
212 throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
213 roleInfo.addRole(role);
214 }
215 }
216 }
217 if (httpMethod == null)
218 {
219 for (Map.Entry<String, RoleInfo> entry : mappings.entrySet())
220 {
221 if (entry.getKey() != null)
222 {
223 RoleInfo specific = entry.getValue();
224 specific.combine(roleInfo);
225 }
226 }
227 }
228 }
229 }
230 }
231 super.doStart();
232 }
233
234 protected Object prepareConstraintInfo(String pathInContext, Request request)
235 {
236 Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.match(pathInContext);
237
238 if (mappings != null)
239 {
240 String httpMethod = request.getMethod();
241 RoleInfo roleInfo = mappings.get(httpMethod);
242 if (roleInfo == null)
243 roleInfo = mappings.get(null);
244 return roleInfo;
245 }
246
247 return null;
248 }
249
250 protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException
251 {
252 if (constraintInfo == null)
253 {
254 return true;
255 }
256 RoleInfo roleInfo = (RoleInfo)constraintInfo;
257 if (roleInfo.isForbidden())
258 {
259 return false;
260 }
261 UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint();
262 if (dataConstraint == null || dataConstraint == UserDataConstraint.None)
263 {
264 return true;
265 }
266 HttpConnection connection = HttpConnection.getCurrentConnection();
267 Connector connector = connection.getConnector();
268
269 if (dataConstraint == UserDataConstraint.Integral)
270 {
271 if (connector.isIntegral(request))
272 return true;
273 if (connector.getConfidentialPort() > 0)
274 {
275 String url = connector.getIntegralScheme() + "://" + request.getServerName() + ":" + connector.getIntegralPort() + request.getRequestURI();
276 if (request.getQueryString() != null)
277 url += "?" + request.getQueryString();
278 response.setContentLength(0);
279 response.sendRedirect(url);
280 request.setHandled(true);
281 }
282 return false;
283 }
284 else if (dataConstraint == UserDataConstraint.Confidential)
285 {
286 if (connector.isConfidential(request))
287 return true;
288
289 if (connector.getConfidentialPort() > 0)
290 {
291 String url = connector.getConfidentialScheme() + "://" + request.getServerName() + ":" + connector.getConfidentialPort()
292 + request.getRequestURI();
293 if (request.getQueryString() != null)
294 url += "?" + request.getQueryString();
295
296 response.setContentLength(0);
297 response.sendRedirect(url);
298 request.setHandled(true);
299 }
300 return false;
301 }
302 else
303 {
304 throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint);
305 }
306
307 }
308
309 protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo)
310 {
311 if (constraintInfo == null)
312 {
313 return false;
314 }
315 return ((RoleInfo)constraintInfo).isChecked();
316 }
317
318 protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity)
319 throws IOException
320 {
321 if (constraintInfo == null)
322 {
323 return true;
324 }
325 RoleInfo roleInfo = (RoleInfo)constraintInfo;
326
327 if (!roleInfo.isChecked())
328 {
329 return true;
330 }
331
332 if (roleInfo.isAnyRole() && request.getAuthType()!=null)
333 return true;
334
335 String[] roles = roleInfo.getRoles();
336 for (String role : roles)
337 {
338 if (userIdentity.isUserInRole(role, null))
339 return true;
340 }
341 return false;
342 }
343 }