1
2
3
4
5
6
7
8
9
10
11
12
13
14 package waffle.spring;
15
16 import java.io.IOException;
17 import java.util.Locale;
18
19 import javax.servlet.FilterChain;
20 import javax.servlet.ServletException;
21 import javax.servlet.ServletRequest;
22 import javax.servlet.ServletResponse;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.springframework.security.core.Authentication;
29 import org.springframework.security.core.GrantedAuthority;
30 import org.springframework.security.core.context.SecurityContextHolder;
31 import org.springframework.web.filter.GenericFilterBean;
32
33 import waffle.servlet.WindowsPrincipal;
34 import waffle.servlet.spi.SecurityFilterProviderCollection;
35 import waffle.util.AuthorizationHeader;
36 import waffle.windows.auth.IWindowsIdentity;
37 import waffle.windows.auth.PrincipalFormat;
38
39
40
41
42
43
44 public class NegotiateSecurityFilter extends GenericFilterBean {
45
46
47 private static final Logger LOGGER = LoggerFactory
48 .getLogger(NegotiateSecurityFilter.class);
49
50
51 private SecurityFilterProviderCollection provider;
52
53
54 private PrincipalFormat principalFormat = PrincipalFormat.FQN;
55
56
57 private PrincipalFormat roleFormat = PrincipalFormat.FQN;
58
59
60 private boolean allowGuestLogin = true;
61
62
63 private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;
64
65
66 private GrantedAuthority defaultGrantedAuthority = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;
67
68
69
70
71 public NegotiateSecurityFilter() {
72 super();
73 NegotiateSecurityFilter.LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded");
74 }
75
76
77
78
79 @Override
80 public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
81 throws IOException, ServletException {
82
83 final HttpServletRequest request = (HttpServletRequest) req;
84 final HttpServletResponse response = (HttpServletResponse) res;
85
86 NegotiateSecurityFilter.LOGGER.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
87 Integer.valueOf(request.getContentLength()));
88
89 final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
90
91
92 if (!authorizationHeader.isNull()
93 && this.provider.isSecurityPackageSupported(authorizationHeader.getSecurityPackage())) {
94
95
96 IWindowsIdentity windowsIdentity;
97
98 try {
99 windowsIdentity = this.provider.doFilter(request, response);
100 if (windowsIdentity == null) {
101 return;
102 }
103 } catch (final IOException e) {
104 NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
105 NegotiateSecurityFilter.LOGGER.trace("{}", e);
106 this.sendUnauthorized(response, true);
107 return;
108 }
109
110 if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
111 NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
112 this.sendUnauthorized(response, true);
113 return;
114 }
115
116 try {
117 NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());
118
119 final WindowsPrincipal principal = new WindowsPrincipal(windowsIdentity, this.principalFormat,
120 this.roleFormat);
121
122 NegotiateSecurityFilter.LOGGER.debug("roles: {}", principal.getRolesString());
123
124 final Authentication authentication = new WindowsAuthenticationToken(principal,
125 this.grantedAuthorityFactory, this.defaultGrantedAuthority);
126
127 if (!this.setAuthentication(request, response, authentication)) {
128 return;
129 }
130
131 NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());
132
133 } finally {
134 windowsIdentity.dispose();
135 }
136 }
137
138 chain.doFilter(request, response);
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response,
159 final Authentication authentication) {
160 SecurityContextHolder.getContext().setAuthentication(authentication);
161 return true;
162 }
163
164
165
166
167 @Override
168 public void afterPropertiesSet() throws ServletException {
169 super.afterPropertiesSet();
170
171 if (this.provider == null) {
172 throw new ServletException("Missing NegotiateSecurityFilter.Provider");
173 }
174 }
175
176
177
178
179
180
181
182
183
184 protected void sendUnauthorized(final HttpServletResponse response, final boolean close) {
185 try {
186 this.provider.sendUnauthorized(response);
187 if (close) {
188 response.setHeader("Connection", "close");
189 } else {
190 response.setHeader("Connection", "keep-alive");
191 }
192 response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
193 response.flushBuffer();
194 } catch (final IOException e) {
195 throw new RuntimeException(e);
196 }
197 }
198
199
200
201
202
203
204 public PrincipalFormat getPrincipalFormat() {
205 return this.principalFormat;
206 }
207
208
209
210
211
212
213
214 public void setPrincipalFormatEnum(final PrincipalFormat value) {
215 this.principalFormat = value;
216 }
217
218
219
220
221
222
223
224 public void setPrincipalFormat(final String value) {
225 this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
226 }
227
228
229
230
231
232
233 public PrincipalFormat getRoleFormat() {
234 return this.roleFormat;
235 }
236
237
238
239
240
241
242
243 public void setRoleFormatEnum(final PrincipalFormat value) {
244 this.roleFormat = value;
245 }
246
247
248
249
250
251
252
253 public void setRoleFormat(final String value) {
254 this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
255 }
256
257
258
259
260
261
262 public boolean isAllowGuestLogin() {
263 return this.allowGuestLogin;
264 }
265
266
267
268
269
270
271
272 public void setAllowGuestLogin(final boolean value) {
273 this.allowGuestLogin = value;
274 }
275
276
277
278
279
280
281 public SecurityFilterProviderCollection getProvider() {
282 return this.provider;
283 }
284
285
286
287
288
289
290
291 public void setProvider(final SecurityFilterProviderCollection value) {
292 this.provider = value;
293 }
294
295
296
297
298
299
300 public GrantedAuthorityFactory getGrantedAuthorityFactory() {
301 return this.grantedAuthorityFactory;
302 }
303
304
305
306
307
308
309
310 public void setGrantedAuthorityFactory(final GrantedAuthorityFactory value) {
311 this.grantedAuthorityFactory = value;
312 }
313
314
315
316
317
318
319 public GrantedAuthority getDefaultGrantedAuthority() {
320 return this.defaultGrantedAuthority;
321 }
322
323
324
325
326
327
328
329 public void setDefaultGrantedAuthority(final GrantedAuthority value) {
330 this.defaultGrantedAuthority = value;
331 }
332 }