PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/JNA/waffle-tomcat85/src/test/java/waffle/apache/MixedAuthenticatorTests.java

http://github.com/dblock/waffle
Java | 386 lines | 262 code | 40 blank | 84 comment | 10 complexity | 5ce7e9a3d6fe14a22c9e80987fcd8684 MD5 | raw file
Possible License(s): MIT, MPL-2.0-no-copyleft-exception, Apache-2.0, LGPL-3.0, LGPL-2.1, GPL-2.0
  1. /**
  2. * Waffle (https://github.com/Waffle/waffle)
  3. *
  4. * Copyright (c) 2010-2018 Application Security, Inc.
  5. *
  6. * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
  7. * Public License v1.0 which accompanies this distribution, and is available at
  8. * https://www.eclipse.org/legal/epl-v10.html.
  9. *
  10. * Contributors: Application Security, Inc.
  11. */
  12. package waffle.apache;
  13. import static org.assertj.core.api.Assertions.assertThat;
  14. import com.sun.jna.platform.win32.Sspi;
  15. import com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc;
  16. import java.util.Base64;
  17. import java.util.Collections;
  18. import javax.servlet.ServletException;
  19. import mockit.Expectations;
  20. import mockit.Mocked;
  21. import org.apache.catalina.Context;
  22. import org.apache.catalina.Engine;
  23. import org.apache.catalina.LifecycleException;
  24. import org.apache.catalina.realm.GenericPrincipal;
  25. import org.junit.jupiter.api.AfterEach;
  26. import org.junit.jupiter.api.Assertions;
  27. import org.junit.jupiter.api.BeforeEach;
  28. import org.junit.jupiter.api.Test;
  29. import waffle.apache.catalina.SimpleHttpRequest;
  30. import waffle.apache.catalina.SimpleHttpResponse;
  31. import waffle.mock.MockWindowsAuthProvider;
  32. import waffle.windows.auth.IWindowsCredentialsHandle;
  33. import waffle.windows.auth.IWindowsIdentity;
  34. import waffle.windows.auth.PrincipalFormat;
  35. import waffle.windows.auth.impl.WindowsAccountImpl;
  36. import waffle.windows.auth.impl.WindowsCredentialsHandleImpl;
  37. import waffle.windows.auth.impl.WindowsSecurityContextImpl;
  38. /**
  39. * Waffle Tomcat Mixed Authenticator Tests.
  40. *
  41. * @author dblock[at]dblock[dot]org
  42. */
  43. public class MixedAuthenticatorTests {
  44. /** The authenticator. */
  45. MixedAuthenticator authenticator;
  46. /** The context. */
  47. @Mocked
  48. Context context;
  49. /** The engine. */
  50. @Mocked
  51. Engine engine;
  52. /**
  53. * Sets the up.
  54. *
  55. * @throws LifecycleException
  56. * the lifecycle exception
  57. */
  58. @BeforeEach
  59. public void setUp() throws LifecycleException {
  60. this.authenticator = new MixedAuthenticator();
  61. this.authenticator.setContainer(this.context);
  62. Assertions.assertNotNull(new Expectations() {
  63. {
  64. MixedAuthenticatorTests.this.context.getParent();
  65. this.result = MixedAuthenticatorTests.this.engine;
  66. MixedAuthenticatorTests.this.context.getParent();
  67. this.result = null;
  68. }
  69. });
  70. this.authenticator.start();
  71. }
  72. /**
  73. * Tear down.
  74. *
  75. * @throws LifecycleException
  76. * the lifecycle exception
  77. */
  78. @AfterEach
  79. public void tearDown() throws LifecycleException {
  80. this.authenticator.stop();
  81. }
  82. /**
  83. * Test challenge get.
  84. */
  85. @Test
  86. public void testChallengeGET() {
  87. final SimpleHttpRequest request = new SimpleHttpRequest();
  88. request.setMethod("GET");
  89. request.setQueryString("j_negotiate_check");
  90. final SimpleHttpResponse response = new SimpleHttpResponse();
  91. this.authenticator.authenticate(request, response);
  92. final String[] wwwAuthenticates = response.getHeaderValues("WWW-Authenticate");
  93. Assertions.assertNotNull(wwwAuthenticates);
  94. Assertions.assertEquals(2, wwwAuthenticates.length);
  95. Assertions.assertEquals("Negotiate", wwwAuthenticates[0]);
  96. Assertions.assertEquals("NTLM", wwwAuthenticates[1]);
  97. Assertions.assertEquals("close", response.getHeader("Connection"));
  98. Assertions.assertEquals(2, response.getHeaderNames().size());
  99. Assertions.assertEquals(401, response.getStatus());
  100. }
  101. /**
  102. * Test challenge post.
  103. */
  104. @Test
  105. public void testChallengePOST() {
  106. final String securityPackage = "Negotiate";
  107. IWindowsCredentialsHandle clientCredentials = null;
  108. WindowsSecurityContextImpl clientContext = null;
  109. try {
  110. // client credentials handle
  111. clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
  112. clientCredentials.initialize();
  113. // initial client security context
  114. clientContext = new WindowsSecurityContextImpl();
  115. clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
  116. clientContext.setCredentialsHandle(clientCredentials);
  117. clientContext.setSecurityPackage(securityPackage);
  118. clientContext.initialize(null, null, WindowsAccountImpl.getCurrentUsername());
  119. final SimpleHttpRequest request = new SimpleHttpRequest();
  120. request.setQueryString("j_negotiate_check");
  121. request.setMethod("POST");
  122. request.setContentLength(0);
  123. final String clientToken = Base64.getEncoder().encodeToString(clientContext.getToken());
  124. request.addHeader("Authorization", securityPackage + " " + clientToken);
  125. final SimpleHttpResponse response = new SimpleHttpResponse();
  126. this.authenticator.authenticate(request, response);
  127. Assertions.assertTrue(response.getHeader("WWW-Authenticate").startsWith(securityPackage + " "));
  128. Assertions.assertEquals("keep-alive", response.getHeader("Connection"));
  129. Assertions.assertEquals(2, response.getHeaderNames().size());
  130. Assertions.assertEquals(401, response.getStatus());
  131. } finally {
  132. if (clientContext != null) {
  133. clientContext.dispose();
  134. }
  135. if (clientCredentials != null) {
  136. clientCredentials.dispose();
  137. }
  138. }
  139. }
  140. /**
  141. * Test get.
  142. */
  143. @Test
  144. public void testGet() {
  145. final SimpleHttpRequest request = new SimpleHttpRequest();
  146. final SimpleHttpResponse response = new SimpleHttpResponse();
  147. Assertions.assertFalse(this.authenticator.authenticate(request, response));
  148. }
  149. /**
  150. * Test get info.
  151. */
  152. @Test
  153. public void testGetInfo() {
  154. assertThat(this.authenticator.getInfo().length()).isGreaterThan(0);
  155. }
  156. /**
  157. * Test negotiate.
  158. */
  159. @Test
  160. public void testNegotiate() {
  161. final String securityPackage = "Negotiate";
  162. IWindowsCredentialsHandle clientCredentials = null;
  163. WindowsSecurityContextImpl clientContext = null;
  164. try {
  165. // client credentials handle
  166. clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
  167. clientCredentials.initialize();
  168. // initial client security context
  169. clientContext = new WindowsSecurityContextImpl();
  170. clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
  171. clientContext.setCredentialsHandle(clientCredentials);
  172. clientContext.setSecurityPackage(securityPackage);
  173. clientContext.initialize(null, null, WindowsAccountImpl.getCurrentUsername());
  174. // negotiate
  175. boolean authenticated = false;
  176. final SimpleHttpRequest request = new SimpleHttpRequest();
  177. request.setQueryString("j_negotiate_check");
  178. String clientToken;
  179. while (true) {
  180. clientToken = Base64.getEncoder().encodeToString(clientContext.getToken());
  181. request.addHeader("Authorization", securityPackage + " " + clientToken);
  182. final SimpleHttpResponse response = new SimpleHttpResponse();
  183. authenticated = this.authenticator.authenticate(request, response);
  184. if (authenticated) {
  185. assertThat(response.getHeaderNames().size()).isGreaterThanOrEqualTo(0);
  186. break;
  187. }
  188. Assertions.assertTrue(response.getHeader("WWW-Authenticate").startsWith(securityPackage + " "));
  189. Assertions.assertEquals("keep-alive", response.getHeader("Connection"));
  190. Assertions.assertEquals(2, response.getHeaderNames().size());
  191. Assertions.assertEquals(401, response.getStatus());
  192. final String continueToken = response.getHeader("WWW-Authenticate")
  193. .substring(securityPackage.length() + 1);
  194. final byte[] continueTokenBytes = Base64.getDecoder().decode(continueToken);
  195. assertThat(continueTokenBytes.length).isGreaterThan(0);
  196. final ManagedSecBufferDesc continueTokenBuffer = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN,
  197. continueTokenBytes);
  198. clientContext.initialize(clientContext.getHandle(), continueTokenBuffer,
  199. WindowsAccountImpl.getCurrentUsername());
  200. }
  201. Assertions.assertTrue(authenticated);
  202. } finally {
  203. if (clientContext != null) {
  204. clientContext.dispose();
  205. }
  206. if (clientCredentials != null) {
  207. clientCredentials.dispose();
  208. }
  209. }
  210. }
  211. /**
  212. * Test post security check.
  213. */
  214. @Test
  215. public void testPostSecurityCheck() {
  216. final SimpleHttpRequest request = new SimpleHttpRequest();
  217. request.setQueryString("j_security_check");
  218. request.addParameter("j_username", "username");
  219. request.addParameter("j_password", "password");
  220. final SimpleHttpResponse response = new SimpleHttpResponse();
  221. Assertions.assertFalse(this.authenticator.authenticate(request, response));
  222. }
  223. /**
  224. * Test programmatic security BOTH.
  225. *
  226. * @param identity
  227. * the identity
  228. * @throws ServletException
  229. * the servlet exception
  230. */
  231. @Test
  232. public void testProgrammaticSecurityBoth(@Mocked final IWindowsIdentity identity) throws ServletException {
  233. this.authenticator.setAuth(new MockWindowsAuthProvider());
  234. final SimpleHttpRequest request = new SimpleHttpRequest();
  235. request.getMappingData().context = (Context) this.authenticator.getContainer();
  236. request.login(WindowsAccountImpl.getCurrentUsername(), "");
  237. Assertions.assertNotNull(new Expectations() {
  238. {
  239. identity.getFqn();
  240. this.result = "fqn";
  241. identity.getSidString();
  242. this.result = "S-1234";
  243. }
  244. });
  245. request.setUserPrincipal(new GenericWindowsPrincipal(identity, PrincipalFormat.BOTH, PrincipalFormat.BOTH));
  246. Assertions.assertTrue(request.getUserPrincipal() instanceof GenericWindowsPrincipal);
  247. final GenericWindowsPrincipal windowsPrincipal = (GenericWindowsPrincipal) request.getUserPrincipal();
  248. Assertions.assertTrue(windowsPrincipal.getSidString().startsWith("S-"));
  249. }
  250. /**
  251. * Test programmatic security SID.
  252. *
  253. * @param identity
  254. * the identity
  255. * @throws ServletException
  256. * the servlet exception
  257. */
  258. @Test
  259. public void testProgrammaticSecuritySID(@Mocked final IWindowsIdentity identity) throws ServletException {
  260. this.authenticator.setAuth(new MockWindowsAuthProvider());
  261. final SimpleHttpRequest request = new SimpleHttpRequest();
  262. request.getMappingData().context = (Context) this.authenticator.getContainer();
  263. request.login(WindowsAccountImpl.getCurrentUsername(), "");
  264. Assertions.assertNotNull(new Expectations() {
  265. {
  266. identity.getSidString();
  267. this.result = "S-1234";
  268. }
  269. });
  270. request.setUserPrincipal(new GenericWindowsPrincipal(identity, PrincipalFormat.SID, PrincipalFormat.SID));
  271. Assertions.assertTrue(request.getUserPrincipal() instanceof GenericWindowsPrincipal);
  272. final GenericWindowsPrincipal windowsPrincipal = (GenericWindowsPrincipal) request.getUserPrincipal();
  273. Assertions.assertTrue(windowsPrincipal.getSidString().startsWith("S-"));
  274. }
  275. /**
  276. * Test programmatic security NONE.
  277. *
  278. * @param identity
  279. * the identity
  280. * @throws ServletException
  281. * the servlet exception
  282. */
  283. @Test
  284. public void testProgrammaticSecurityNone(@Mocked final IWindowsIdentity identity) throws ServletException {
  285. this.authenticator.setAuth(new MockWindowsAuthProvider());
  286. final SimpleHttpRequest request = new SimpleHttpRequest();
  287. request.getMappingData().context = (Context) this.authenticator.getContainer();
  288. request.login(WindowsAccountImpl.getCurrentUsername(), "");
  289. request.setUserPrincipal(new GenericWindowsPrincipal(identity, PrincipalFormat.NONE, PrincipalFormat.NONE));
  290. Assertions.assertTrue(request.getUserPrincipal() instanceof GenericWindowsPrincipal);
  291. final GenericWindowsPrincipal windowsPrincipal = (GenericWindowsPrincipal) request.getUserPrincipal();
  292. Assertions.assertNull(windowsPrincipal.getSidString());
  293. }
  294. /**
  295. * Test security check parameters.
  296. */
  297. @Test
  298. public void testSecurityCheckParameters() {
  299. this.authenticator.setAuth(new MockWindowsAuthProvider());
  300. final SimpleHttpRequest request = new SimpleHttpRequest();
  301. request.addParameter("j_security_check", "");
  302. request.addParameter("j_username", WindowsAccountImpl.getCurrentUsername());
  303. request.addParameter("j_password", "");
  304. final SimpleHttpResponse response = new SimpleHttpResponse();
  305. Assertions.assertTrue(this.authenticator.authenticate(request, response));
  306. }
  307. /**
  308. * Test security check query string.
  309. */
  310. @Test
  311. public void testSecurityCheckQueryString() {
  312. this.authenticator.setAuth(new MockWindowsAuthProvider());
  313. final SimpleHttpRequest request = new SimpleHttpRequest();
  314. request.setQueryString("j_security_check");
  315. request.addParameter("j_username", WindowsAccountImpl.getCurrentUsername());
  316. request.addParameter("j_password", "");
  317. final SimpleHttpResponse response = new SimpleHttpResponse();
  318. Assertions.assertTrue(this.authenticator.authenticate(request, response));
  319. }
  320. @Test
  321. public void testCustomPrincipal() throws LifecycleException {
  322. final GenericPrincipal genericPrincipal = new GenericPrincipal("my-principal", "my-password",
  323. Collections.emptyList());
  324. final MixedAuthenticator customAuthenticator = new MixedAuthenticator() {
  325. @Override
  326. protected GenericPrincipal createPrincipal(final IWindowsIdentity windowsIdentity) {
  327. return genericPrincipal;
  328. }
  329. };
  330. try {
  331. customAuthenticator.setContainer(this.context);
  332. customAuthenticator.setAlwaysUseSession(true);
  333. customAuthenticator.start();
  334. customAuthenticator.setAuth(new MockWindowsAuthProvider());
  335. final SimpleHttpRequest request = new SimpleHttpRequest();
  336. request.addParameter("j_security_check", "");
  337. request.addParameter("j_username", WindowsAccountImpl.getCurrentUsername());
  338. request.addParameter("j_password", "");
  339. final SimpleHttpResponse response = new SimpleHttpResponse();
  340. Assertions.assertTrue(customAuthenticator.authenticate(request, response));
  341. Assertions.assertEquals(genericPrincipal, request.getUserPrincipal());
  342. } finally {
  343. customAuthenticator.stop();
  344. }
  345. }
  346. }