• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Waffle / waffle / 6364

01 Feb 2026 02:07AM UTC coverage: 46.217%. Remained the same
6364

push

github

web-flow
Merge pull request #3206 from Waffle/renovate/checkstyle.version

Update dependency com.puppycrawl.tools:checkstyle to v13.1.0

276 of 734 branches covered (37.6%)

Branch coverage included in aggregate %.

1019 of 2068 relevant lines covered (49.27%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.9
/Source/JNA/waffle-spring-security5/src/main/java/waffle/spring/NegotiateSecurityFilter.java
1
/*
2
 * SPDX-License-Identifier: MIT
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2010-2026 The Waffle Project Contributors: https://github.com/Waffle/waffle/graphs/contributors
6
 */
7
package waffle.spring;
8

9
import java.io.IOException;
10
import java.util.Locale;
11

12
import javax.servlet.FilterChain;
13
import javax.servlet.ServletException;
14
import javax.servlet.ServletRequest;
15
import javax.servlet.ServletResponse;
16
import javax.servlet.http.HttpServletRequest;
17
import javax.servlet.http.HttpServletResponse;
18

19
import org.slf4j.Logger;
20
import org.slf4j.LoggerFactory;
21
import org.springframework.security.core.Authentication;
22
import org.springframework.security.core.GrantedAuthority;
23
import org.springframework.security.core.context.SecurityContextHolder;
24
import org.springframework.web.filter.GenericFilterBean;
25

26
import waffle.servlet.AutoDisposableWindowsPrincipal;
27
import waffle.servlet.WindowsPrincipal;
28
import waffle.servlet.spi.SecurityFilterProviderCollection;
29
import waffle.util.AuthorizationHeader;
30
import waffle.windows.auth.IWindowsIdentity;
31
import waffle.windows.auth.IWindowsImpersonationContext;
32
import waffle.windows.auth.PrincipalFormat;
33

34
/**
35
 * A Spring Negotiate security filter.
36
 */
37
public class NegotiateSecurityFilter extends GenericFilterBean {
38

39
    /** The Constant LOGGER. */
40
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilter.class);
3✔
41

42
    /** The provider. */
43
    private SecurityFilterProviderCollection provider;
44

45
    /** The principal format. */
46
    private PrincipalFormat principalFormat = PrincipalFormat.FQN;
3✔
47

48
    /** The role format. */
49
    private PrincipalFormat roleFormat = PrincipalFormat.FQN;
3✔
50

51
    /** The allow guest login. */
52
    private boolean allowGuestLogin = true;
3✔
53

54
    /** The impersonate. */
55
    private boolean impersonate;
56

57
    /** The granted authority factory. */
58
    private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;
3✔
59

60
    /** The default granted authority. */
61
    private GrantedAuthority defaultGrantedAuthority = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;
3✔
62

63
    /**
64
     * Instantiates a new negotiate security filter.
65
     */
66
    public NegotiateSecurityFilter() {
67
        super();
3✔
68
        NegotiateSecurityFilter.LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded");
3✔
69
    }
3✔
70

71
    @Override
72
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
73
            throws IOException, ServletException {
74

75
        final HttpServletRequest request = (HttpServletRequest) req;
3✔
76
        final HttpServletResponse response = (HttpServletResponse) res;
3✔
77

78
        NegotiateSecurityFilter.LOGGER.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
3✔
79
                Integer.valueOf(request.getContentLength()));
3✔
80

81
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
3✔
82

83
        // authenticate user
84
        if (!authorizationHeader.isNull()
3✔
85
                && this.provider.isSecurityPackageSupported(authorizationHeader.getSecurityPackage())) {
3✔
86

87
            // log the user in using the token
88
            IWindowsIdentity windowsIdentity;
89

90
            try {
91
                windowsIdentity = this.provider.doFilter(request, response);
3✔
92
                if (windowsIdentity == null) {
3!
93
                    return;
×
94
                }
95
            } catch (final IOException e) {
×
96
                NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
×
97
                NegotiateSecurityFilter.LOGGER.trace("", e);
×
98
                this.sendUnauthorized(response, true);
×
99
                return;
×
100
            }
3✔
101

102
            IWindowsImpersonationContext ctx = null;
3✔
103
            try {
104
                if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
3✔
105
                    NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
3✔
106
                    this.sendUnauthorized(response, true);
3✔
107
                    return;
3✔
108
                }
109

110
                NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
3✔
111
                        windowsIdentity.getSidString());
3✔
112

113
                final WindowsPrincipal principal = this.impersonate
3✔
114
                        ? new AutoDisposableWindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat)
3✔
115
                        : new WindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);
3✔
116

117
                NegotiateSecurityFilter.LOGGER.debug("roles: {}", principal.getRolesString());
3✔
118

119
                final Authentication authentication = new WindowsAuthenticationToken(principal,
3✔
120
                        this.grantedAuthorityFactory, this.defaultGrantedAuthority);
121

122
                if (!this.setAuthentication(request, response, authentication)) {
3!
123
                    return;
×
124
                }
125

126
                NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());
3✔
127

128
                if (this.impersonate) {
3✔
129
                    NegotiateSecurityFilter.LOGGER.debug("impersonating user");
3✔
130
                    ctx = windowsIdentity.impersonate();
3✔
131
                }
132

133
                chain.doFilter(request, response);
3✔
134
            } finally {
135
                if (this.impersonate && ctx != null) {
3!
136
                    NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
3✔
137
                    ctx.revertToSelf();
3✔
138
                } else {
139
                    windowsIdentity.dispose();
3✔
140
                }
141
            }
142
        } else {
3✔
143
            chain.doFilter(request, response);
3✔
144
        }
145
    }
3✔
146

147
    /**
148
     * Invoked when authentication towards ad was succesful to populate securitycontext Override to add service provider
149
     * authorization checks.
150
     *
151
     * @param request
152
     *            the request
153
     * @param response
154
     *            the response
155
     * @param authentication
156
     *            the authentication
157
     *
158
     * @return true, if successful
159
     */
160
    protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response,
161
            final Authentication authentication) {
162
        SecurityContextHolder.getContext().setAuthentication(authentication);
3✔
163
        return true;
3✔
164
    }
165

166
    @Override
167
    public void afterPropertiesSet() throws ServletException {
168
        super.afterPropertiesSet();
3✔
169

170
        if (this.provider == null) {
3✔
171
            throw new ServletException("Missing NegotiateSecurityFilter.Provider");
3✔
172
        }
173
    }
3✔
174

175
    /**
176
     * Send a 401 Unauthorized along with protocol authentication headers.
177
     *
178
     * @param response
179
     *            HTTP Response
180
     * @param close
181
     *            Close connection.
182
     */
183
    protected void sendUnauthorized(final HttpServletResponse response, final boolean close) {
184
        try {
185
            this.provider.sendUnauthorized(response);
3✔
186
            if (close) {
3!
187
                response.setHeader("Connection", "close");
3✔
188
            } else {
189
                response.setHeader("Connection", "keep-alive");
×
190
            }
191
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
3✔
192
            response.flushBuffer();
3✔
193
        } catch (final IOException e) {
×
194
            throw new RuntimeException(e);
×
195
        }
3✔
196
    }
3✔
197

198
    /**
199
     * Gets the principal format.
200
     *
201
     * @return the principal format
202
     */
203
    public PrincipalFormat getPrincipalFormat() {
204
        return this.principalFormat;
3✔
205
    }
206

207
    /**
208
     * Sets the principal format enum.
209
     *
210
     * @param value
211
     *            the new principal format enum
212
     */
213
    public void setPrincipalFormatEnum(final PrincipalFormat value) {
214
        this.principalFormat = value;
3✔
215
    }
3✔
216

217
    /**
218
     * Sets the principal format.
219
     *
220
     * @param value
221
     *            the new principal format
222
     */
223
    public void setPrincipalFormat(final String value) {
224
        this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
3✔
225
    }
3✔
226

227
    /**
228
     * Gets the role format.
229
     *
230
     * @return the role format
231
     */
232
    public PrincipalFormat getRoleFormat() {
233
        return this.roleFormat;
3✔
234
    }
235

236
    /**
237
     * Sets the role format enum.
238
     *
239
     * @param value
240
     *            the new role format enum
241
     */
242
    public void setRoleFormatEnum(final PrincipalFormat value) {
243
        this.roleFormat = value;
3✔
244
    }
3✔
245

246
    /**
247
     * Sets the role format.
248
     *
249
     * @param value
250
     *            the new role format
251
     */
252
    public void setRoleFormat(final String value) {
253
        this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
3✔
254
    }
3✔
255

256
    /**
257
     * Checks if is allow guest login.
258
     *
259
     * @return true, if is allow guest login
260
     */
261
    public boolean isAllowGuestLogin() {
262
        return this.allowGuestLogin;
3✔
263
    }
264

265
    /**
266
     * Sets the allow guest login.
267
     *
268
     * @param value
269
     *            the new allow guest login
270
     */
271
    public void setAllowGuestLogin(final boolean value) {
272
        this.allowGuestLogin = value;
3✔
273
    }
3✔
274

275
    /**
276
     * Enable/Disable impersonation.
277
     *
278
     * @param value
279
     *            true to enable impersonation, false otherwise
280
     */
281
    public void setImpersonate(final boolean value) {
282
        this.impersonate = value;
3✔
283
    }
3✔
284

285
    /**
286
     * Checks if is impersonate.
287
     *
288
     * @return true if impersonation is enabled, false otherwise
289
     */
290
    public boolean isImpersonate() {
291
        return this.impersonate;
×
292
    }
293

294
    /**
295
     * Gets the provider.
296
     *
297
     * @return the provider
298
     */
299
    public SecurityFilterProviderCollection getProvider() {
300
        return this.provider;
3✔
301
    }
302

303
    /**
304
     * Sets the provider.
305
     *
306
     * @param value
307
     *            the new provider
308
     */
309
    public void setProvider(final SecurityFilterProviderCollection value) {
310
        this.provider = value;
3✔
311
    }
3✔
312

313
    /**
314
     * Gets the granted authority factory.
315
     *
316
     * @return the granted authority factory
317
     */
318
    public GrantedAuthorityFactory getGrantedAuthorityFactory() {
319
        return this.grantedAuthorityFactory;
×
320
    }
321

322
    /**
323
     * Sets the granted authority factory.
324
     *
325
     * @param value
326
     *            the new granted authority factory
327
     */
328
    public void setGrantedAuthorityFactory(final GrantedAuthorityFactory value) {
329
        this.grantedAuthorityFactory = value;
×
330
    }
×
331

332
    /**
333
     * Gets the default granted authority.
334
     *
335
     * @return the default granted authority
336
     */
337
    public GrantedAuthority getDefaultGrantedAuthority() {
338
        return this.defaultGrantedAuthority;
×
339
    }
340

341
    /**
342
     * Sets the default granted authority.
343
     *
344
     * @param value
345
     *            the new default granted authority
346
     */
347
    public void setDefaultGrantedAuthority(final GrantedAuthority value) {
348
        this.defaultGrantedAuthority = value;
×
349
    }
×
350
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc