1
2
3
4
5
6
7
8
9
10
11
12
13
14 package waffle.servlet.spi;
15
16 import java.io.IOException;
17 import java.lang.reflect.Constructor;
18 import java.lang.reflect.InvocationTargetException;
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import com.sun.jna.platform.win32.Win32Exception;
29
30 import waffle.util.AuthorizationHeader;
31 import waffle.windows.auth.IWindowsAuthProvider;
32 import waffle.windows.auth.IWindowsIdentity;
33
34
35
36
37
38
39 public class SecurityFilterProviderCollection {
40
41
42 private static final Logger LOGGER = LoggerFactory.getLogger(SecurityFilterProviderCollection.class);
43
44
45 private final List<SecurityFilterProvider> providers = new ArrayList<SecurityFilterProvider>();
46
47
48
49
50
51
52
53 public SecurityFilterProviderCollection(final SecurityFilterProvider[] providerArray) {
54 for (final SecurityFilterProvider provider : providerArray) {
55 SecurityFilterProviderCollection.LOGGER.info("using '{}'", provider.getClass().getName());
56 this.providers.add(provider);
57 }
58 }
59
60
61
62
63
64
65
66
67
68 @SuppressWarnings("unchecked")
69 public SecurityFilterProviderCollection(final String[] providerNames, final IWindowsAuthProvider auth) {
70 Class<SecurityFilterProvider> providerClass;
71 Constructor<SecurityFilterProvider> providerConstructor;
72 for (String providerName : providerNames) {
73 providerName = providerName.trim();
74 SecurityFilterProviderCollection.LOGGER.info("loading '{}'", providerName);
75 try {
76 providerClass = (Class<SecurityFilterProvider>) Class.forName(providerName);
77 providerConstructor = providerClass.getConstructor(IWindowsAuthProvider.class);
78 final SecurityFilterProvider provider = providerConstructor.newInstance(auth);
79 this.providers.add(provider);
80 } catch (final ClassNotFoundException e) {
81 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
82 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
83 throw new RuntimeException(e);
84 } catch (final SecurityException e) {
85 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
86 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
87 } catch (final NoSuchMethodException e) {
88 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
89 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
90 } catch (final IllegalArgumentException e) {
91 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
92 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
93 } catch (final InstantiationException e) {
94 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
95 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
96 } catch (final IllegalAccessException e) {
97 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
98 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
99 } catch (final InvocationTargetException e) {
100 SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
101 SecurityFilterProviderCollection.LOGGER.trace("{}", e);
102 }
103 }
104 }
105
106
107
108
109
110
111
112 public SecurityFilterProviderCollection(final IWindowsAuthProvider auth) {
113 this.providers.add(new NegotiateSecurityFilterProvider(auth));
114 this.providers.add(new BasicSecurityFilterProvider(auth));
115 }
116
117
118
119
120
121
122
123
124 public boolean isSecurityPackageSupported(final String securityPackage) {
125 return this.get(securityPackage) != null;
126 }
127
128
129
130
131
132
133
134
135 private SecurityFilterProvider get(final String securityPackage) {
136 for (final SecurityFilterProvider provider : this.providers) {
137 if (provider.isSecurityPackageSupported(securityPackage)) {
138 return provider;
139 }
140 }
141 return null;
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155 public IWindowsIdentity doFilter(final HttpServletRequest request, final HttpServletResponse response)
156 throws IOException {
157 final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
158 final SecurityFilterProvider provider = this.get(authorizationHeader.getSecurityPackage());
159 if (provider == null) {
160 throw new RuntimeException("Unsupported security package: " + authorizationHeader.getSecurityPackage());
161 }
162 try {
163 return provider.doFilter(request, response);
164 } catch (final Win32Exception e) {
165 throw new IOException(e);
166 }
167 }
168
169
170
171
172
173
174
175
176 public boolean isPrincipalException(final HttpServletRequest request) {
177 for (final SecurityFilterProvider provider : this.providers) {
178 if (provider.isPrincipalException(request)) {
179 return true;
180 }
181 }
182 return false;
183 }
184
185
186
187
188
189
190
191 public void sendUnauthorized(final HttpServletResponse response) {
192 for (final SecurityFilterProvider provider : this.providers) {
193 provider.sendUnauthorized(response);
194 }
195 }
196
197
198
199
200
201
202 public int size() {
203 return this.providers.size();
204 }
205
206
207
208
209
210
211
212
213
214
215 public SecurityFilterProvider getByClassName(final String name) throws ClassNotFoundException {
216 for (final SecurityFilterProvider provider : this.providers) {
217 if (provider.getClass().getName().equals(name)) {
218 return provider;
219 }
220 }
221 throw new ClassNotFoundException(name);
222 }
223 }