1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.annotations;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import javax.servlet.ServletSecurityElement;
25 import javax.servlet.annotation.ServletSecurity;
26 import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
27 import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
28
29 import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
30 import org.eclipse.jetty.security.ConstraintAware;
31 import org.eclipse.jetty.security.ConstraintMapping;
32 import org.eclipse.jetty.security.ConstraintSecurityHandler;
33 import org.eclipse.jetty.servlet.ServletHolder;
34 import org.eclipse.jetty.servlet.ServletMapping;
35 import org.eclipse.jetty.util.log.Log;
36 import org.eclipse.jetty.util.log.Logger;
37 import org.eclipse.jetty.util.security.Constraint;
38 import org.eclipse.jetty.webapp.Origin;
39 import org.eclipse.jetty.webapp.WebAppContext;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnnotationHandler
59 {
60 private static final Logger LOG = Log.getLogger(ServletSecurityAnnotationHandler.class);
61
62 private WebAppContext _context;
63
64 public ServletSecurityAnnotationHandler(WebAppContext wac)
65 {
66 super(false);
67 _context = wac;
68 }
69
70
71
72
73 public void doHandle(Class clazz)
74 {
75 if (!(_context.getSecurityHandler() instanceof ConstraintAware))
76 {
77 LOG.warn("SecurityHandler not ConstraintAware, skipping security annotation processing");
78 return;
79 }
80
81 ServletSecurity servletSecurity = (ServletSecurity)clazz.getAnnotation(ServletSecurity.class);
82 if (servletSecurity == null)
83 return;
84
85
86
87
88 List<ServletMapping> servletMappings = getServletMappings(clazz.getCanonicalName());
89 List<ConstraintMapping> constraintMappings = ((ConstraintAware)_context.getSecurityHandler()).getConstraintMappings();
90
91 if (constraintsExist(servletMappings, constraintMappings))
92 {
93 LOG.warn("Constraints already defined for "+clazz.getName()+", skipping ServletSecurity annotation");
94 return;
95 }
96
97
98 constraintMappings = new ArrayList<ConstraintMapping>();
99
100 ServletSecurityElement securityElement = new ServletSecurityElement(servletSecurity);
101 for (ServletMapping sm : servletMappings)
102 {
103 for (String url : sm.getPathSpecs())
104 {
105 _context.getMetaData().setOrigin("constraint.url."+url, Origin.Annotation);
106 constraintMappings.addAll(ConstraintSecurityHandler.createConstraintsWithMappingsForPath(clazz.getName(), url, securityElement));
107 }
108 }
109
110
111 ConstraintAware securityHandler = (ConstraintAware)_context.getSecurityHandler();
112
113 for (ConstraintMapping m:constraintMappings)
114 securityHandler.addConstraintMapping(m);
115
116
117 securityHandler.checkPathsWithUncoveredHttpMethods();
118 }
119
120
121
122
123
124
125
126
127
128
129
130 protected Constraint makeConstraint (Class servlet, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport)
131 {
132 return ConstraintSecurityHandler.createConstraint(servlet.getName(), rolesAllowed, permitOrDeny, transport);
133 }
134
135
136
137
138
139
140
141 protected List<ServletMapping> getServletMappings(String className)
142 {
143 List<ServletMapping> results = new ArrayList<ServletMapping>();
144 ServletMapping[] mappings = _context.getServletHandler().getServletMappings();
145 for (ServletMapping mapping : mappings)
146 {
147
148 ServletHolder holder = _context.getServletHandler().getServlet(mapping.getServletName());
149 if (holder.getClassName() != null && holder.getClassName().equals(className))
150 results.add(mapping);
151 }
152 return results;
153 }
154
155
156
157
158
159
160
161
162 protected boolean constraintsExist (List<ServletMapping> servletMappings, List<ConstraintMapping> constraintMappings)
163 {
164 boolean exists = false;
165
166
167
168 for (ServletMapping mapping : servletMappings)
169 {
170
171 String[] pathSpecs = mapping.getPathSpecs();
172 if (pathSpecs == null)
173 continue;
174
175
176
177
178 for (int i=0; constraintMappings != null && i < constraintMappings.size() && !exists; i++)
179 {
180 for (int j=0; j < pathSpecs.length; j++)
181 {
182
183 if (pathSpecs[j].equals(constraintMappings.get(i).getPathSpec()))
184 {
185 exists = true;
186 break;
187 }
188 }
189 }
190 }
191 return exists;
192 }
193
194 }