1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package waffle.spring;
25
26 import java.io.IOException;
27 import java.nio.charset.StandardCharsets;
28 import java.util.ArrayList;
29 import java.util.Base64;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.List;
33
34 import javax.servlet.ServletException;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpServletResponse;
37
38 import org.junit.jupiter.api.AfterEach;
39 import org.junit.jupiter.api.Assertions;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.junit.jupiter.api.condition.DisabledOnJre;
43 import org.junit.jupiter.api.condition.JRE;
44 import org.mockito.Mockito;
45 import org.springframework.context.ApplicationContext;
46 import org.springframework.context.support.AbstractApplicationContext;
47 import org.springframework.context.support.ClassPathXmlApplicationContext;
48 import org.springframework.security.core.Authentication;
49 import org.springframework.security.core.GrantedAuthority;
50 import org.springframework.security.core.context.SecurityContextHolder;
51 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
52
53 import waffle.mock.http.SimpleFilterChain;
54 import waffle.mock.http.SimpleHttpRequest;
55 import waffle.mock.http.SimpleHttpResponse;
56 import waffle.spring.handlers.CustomAccessDeniedHandler;
57 import waffle.windows.auth.PrincipalFormat;
58 import waffle.windows.auth.impl.WindowsAccountImpl;
59
60
61
62
63
64
65 class DelegatingNegotiateSecurityFilterTest {
66
67
68 private DelegatingNegotiateSecurityFilter filter;
69
70
71 private ApplicationContext ctx;
72
73
74
75
76 @BeforeEach
77 void setUp() {
78 final String[] configFiles = new String[] { "springTestFilterBeans.xml" };
79 this.ctx = new ClassPathXmlApplicationContext(configFiles);
80 SecurityContextHolder.getContext().setAuthentication(null);
81 this.filter = (DelegatingNegotiateSecurityFilter) this.ctx.getBean("waffleDelegatingNegotiateSecurityFilter");
82 }
83
84
85
86
87 @AfterEach
88 void shutDown() {
89 ((AbstractApplicationContext) this.ctx).close();
90 }
91
92
93
94
95 @Test
96 void testFilter() {
97 Assertions.assertFalse(this.filter.isAllowGuestLogin());
98 Assertions.assertEquals(PrincipalFormat.FQN, this.filter.getPrincipalFormat());
99 Assertions.assertEquals(PrincipalFormat.BOTH, this.filter.getRoleFormat());
100 Assertions.assertNull(this.filter.getFilterConfig());
101 Assertions.assertNotNull(this.filter.getProvider());
102 Assertions.assertTrue(this.filter.getAccessDeniedHandler() instanceof CustomAccessDeniedHandler);
103 }
104
105
106
107
108
109
110
111
112
113
114 @Test
115 void testNegotiate() throws IOException, ServletException {
116 final String securityPackage = "Negotiate";
117 final SimpleFilterChain filterChain = new SimpleFilterChain();
118 final SimpleHttpRequest request = new SimpleHttpRequest();
119
120 final String clientToken = Base64.getEncoder()
121 .encodeToString(WindowsAccountImpl.getCurrentUsername().getBytes(StandardCharsets.UTF_8));
122 request.addHeader("Authorization", securityPackage + " " + clientToken);
123
124 final SimpleHttpResponse response = new SimpleHttpResponse();
125 this.filter.doFilter(request, response, filterChain);
126
127 final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
128 Assertions.assertNotNull(auth);
129 final Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
130 Assertions.assertNotNull(authorities);
131 Assertions.assertEquals(3, authorities.size());
132
133 final List<String> list = new ArrayList<>();
134 for (final GrantedAuthority grantedAuthority : authorities) {
135 list.add(grantedAuthority.getAuthority());
136 }
137 Collections.sort(list);
138 Assertions.assertEquals("ROLE_EVERYONE", list.get(0));
139 Assertions.assertEquals("ROLE_USER", list.get(1));
140 Assertions.assertEquals("ROLE_USERS", list.get(2));
141 Assertions.assertEquals(0, response.getHeaderNamesSize());
142 }
143
144
145
146
147
148
149
150
151
152
153 @Test
154 @DisabledOnJre(JRE.JAVA_21)
155 void testNegotiate_CustomAuth() throws IOException, ServletException {
156 final Authentication customToken = Mockito.mock(Authentication.class);
157 Mockito.when(customToken.getName()).thenReturn("Custom Token");
158 this.filter.setAuthenticationManager(authentication -> customToken);
159
160 final CustomAuthenticationSuccessHandler successHandler = new CustomAuthenticationSuccessHandler();
161 this.filter.setAuthenticationSuccessHandler(successHandler);
162
163 final String securityPackage = "Negotiate";
164 final SimpleFilterChain filterChain = new SimpleFilterChain();
165 final SimpleHttpRequest request = new SimpleHttpRequest();
166
167 final String clientToken = Base64.getEncoder()
168 .encodeToString(WindowsAccountImpl.getCurrentUsername().getBytes(StandardCharsets.UTF_8));
169 request.addHeader("Authorization", securityPackage + " " + clientToken);
170
171 final SimpleHttpResponse response = new SimpleHttpResponse();
172 this.filter.doFilter(request, response, filterChain);
173
174 final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
175 Assertions.assertNotNull(auth);
176 Assertions.assertEquals(customToken, auth);
177 Assertions.assertEquals("Custom Token", auth.getName());
178
179 Assertions.assertEquals(customToken, successHandler.getAuthentication());
180 Assertions.assertEquals("Custom Token", successHandler.getAuthentication().getName());
181 }
182
183 }
184
185
186
187
188
189
190
191 class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
192
193 private Authentication authentication;
194
195 @Override
196 public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
197 Authentication authentication) throws IOException, ServletException {
198 this.authentication = authentication;
199 }
200
201 public Authentication getAuthentication() {
202 return authentication;
203 }
204 }