diff --git a/.gitignore b/.gitignore index 65f80aea14..23be3806f6 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ Waffle.sln.cache Waffle.suo *.csproj.user .tern-project +*.iml diff --git a/CHANGELOG.md b/CHANGELOG.md index 325465a3b5..7b5e8e6622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Rework .net build to be mostly automatic using nuget * Change .net target to more modern .net 4.0 framework +* [#309](https://github.com/dblock/waffle/pull/309): Added impersonation support on spring-security filters [@sergey-podolsky](https://github.com/sergey-podolsky). * [#296](https://github.com/dblock/waffle/pull/296): Added Tomcat 9 support. * [#268](https://github.com/dblock/waffle/pull/301): Cannot log in automatically on machine where Tomcat service is running * [#274](https://github.com/dblock/waffle/pull/274): Update WindowsSecurityContextImpl.java to handle SEC_E_BUFFER_TOO_SMALL diff --git a/Docs/spring/SpringSecuritySingleSignOnFilter.md b/Docs/spring/SpringSecuritySingleSignOnFilter.md index 8c05d114c9..0d9510290c 100644 --- a/Docs/spring/SpringSecuritySingleSignOnFilter.md +++ b/Docs/spring/SpringSecuritySingleSignOnFilter.md @@ -112,6 +112,7 @@ The `waffleNegotiateSecurityFilter` bean can be configured with the following op * principalFormat: Specifies the name format for the principal. * roleFormat: Specifies the name format for the role. * allowGuestLogin: Allow guest login. When true and the system's Guest account is enabled, any invalid login succeeds as Guest. Note that while the default value of allowGuestLogin is true, it is recommended that you disable the system's Guest account to disallow Guest login. This option is provided for systems where you don't have administrative privileges. +* impersonate: Allow impersonation. When true the remote user will be impersonated. Note that there is no mapping between the Windows native threads, under which the impersonation takes place, and the Java threads. Thus you'll need to use Windows native APIs to perform impersonated actions. Any action done in Java will still be performed with the user account running the servlet container. * defaultGrantedAuthority: Specifies the `GrantedAuthority` to be added to every successfully authenticated user. By default, the `defaultGrantedAuthority` will add a `GrantedAuthority` for `ROLE_USER`. If you do not want this behavior, you can set the `defaultGrantedAuthority` to `null` (if you do not want a `GrantedAuthority` to be added by default), or some other `GrantedAuthority`. * grantedAuthorityFactory: Used to create `GrantedAuthority` objects for each of the groups to which the authenticated user belongs. The default `grantedAuthorityFactory` will construct `GrantedAuthority` objects whose string is the uppercase group name prefixed with `ROLE_`. @@ -119,6 +120,7 @@ The `waffleNegotiateSecurityFilter` bean can be configured with the following op + diff --git a/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java b/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java index 3d90ca1501..84e90a6cdb 100644 --- a/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java +++ b/Source/JNA/waffle-spring-security3/src/main/java/waffle/spring/NegotiateSecurityFilter.java @@ -30,10 +30,12 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; +import waffle.servlet.AutoDisposableWindowsPrincipal; import waffle.servlet.WindowsPrincipal; import waffle.servlet.spi.SecurityFilterProviderCollection; import waffle.util.AuthorizationHeader; import waffle.windows.auth.IWindowsIdentity; +import waffle.windows.auth.IWindowsImpersonationContext; import waffle.windows.auth.PrincipalFormat; /** @@ -59,6 +61,9 @@ public class NegotiateSecurityFilter extends GenericFilterBean { /** The allow guest login. */ private boolean allowGuestLogin = true; + /** The impersonate. */ + private boolean impersonate; + /** The granted authority factory. */ private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY; @@ -115,12 +120,14 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final return; } + IWindowsImpersonationContext ctx = null; try { NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString()); - final WindowsPrincipal principal = new WindowsPrincipal(windowsIdentity, this.principalFormat, - this.roleFormat); + final WindowsPrincipal principal = impersonate ? new AutoDisposableWindowsPrincipal(windowsIdentity, + this.principalFormat, this.roleFormat) : new WindowsPrincipal(windowsIdentity, + this.principalFormat, this.roleFormat); NegotiateSecurityFilter.LOGGER.debug("roles: {}", principal.getRolesString()); @@ -133,12 +140,23 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn()); + if (this.impersonate) { + LOGGER.debug("impersonating user"); + ctx = windowsIdentity.impersonate(); + } + + chain.doFilter(request, response); } finally { - windowsIdentity.dispose(); + if (this.impersonate && ctx != null) { + NegotiateSecurityFilter.LOGGER.debug("terminating impersonation"); + ctx.revertToSelf(); + } else { + windowsIdentity.dispose(); + } } + } else { + chain.doFilter(request, response); } - - chain.doFilter(request, response); } /* @@ -276,6 +294,25 @@ public void setAllowGuestLogin(final boolean value) { this.allowGuestLogin = value; } + /** + * Enable/Disable impersonation. + * + * @param value + * true to enable impersonation, false otherwise + */ + public void setImpersonate(final boolean value) { + this.impersonate = value; + } + + /** + * Checks if is impersonate. + * + * @return true if impersonation is enabled, false otherwise + */ + public boolean isImpersonate() { + return this.impersonate; + } + /** * Gets the provider. * diff --git a/Source/JNA/waffle-spring-security3/src/test/java/waffle/spring/ImpersonateTests.java b/Source/JNA/waffle-spring-security3/src/test/java/waffle/spring/ImpersonateTests.java new file mode 100644 index 0000000000..695d680819 --- /dev/null +++ b/Source/JNA/waffle-spring-security3/src/test/java/waffle/spring/ImpersonateTests.java @@ -0,0 +1,180 @@ +/** + * Waffle (https://github.com/dblock/waffle) + * + * Copyright (c) 2010 - 2015 Application Security, Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Application Security, Inc. + */ +package waffle.spring; + +import com.google.common.base.Charsets; +import com.google.common.io.BaseEncoding; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Advapi32Util; +import com.sun.jna.platform.win32.LMAccess; +import com.sun.jna.platform.win32.LMErr; +import com.sun.jna.platform.win32.Netapi32; +import org.junit.After; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import waffle.mock.MockWindowsAccount; +import waffle.mock.http.RecordUserNameFilterChain; +import waffle.mock.http.SimpleHttpRequest; +import waffle.mock.http.SimpleHttpResponse; +import waffle.servlet.AutoDisposableWindowsPrincipal; +import waffle.servlet.WindowsPrincipal; +import waffle.servlet.spi.SecurityFilterProviderCollection; +import waffle.windows.auth.impl.WindowsAuthProviderImpl; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.security.Principal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.is; + +/** + * The Class ImpersonateTests. + */ +public class ImpersonateTests { + + /** The filter. */ + private waffle.spring.NegotiateSecurityFilter filter; + + /** The user info. */ + private LMAccess.USER_INFO_1 userInfo; + + /** The result of net add user. */ + private int resultOfNetAddUser; + + /** + * Sets the up. + */ + @Before + public void setUp() { + this.filter = new NegotiateSecurityFilter(); + this.filter.setProvider(new SecurityFilterProviderCollection(new WindowsAuthProviderImpl())); + + this.userInfo = new LMAccess.USER_INFO_1(); + this.userInfo.usri1_name = new WString(MockWindowsAccount.TEST_USER_NAME); + this.userInfo.usri1_password = new WString(MockWindowsAccount.TEST_PASSWORD); + this.userInfo.usri1_priv = LMAccess.USER_PRIV_USER; + + this.resultOfNetAddUser = Netapi32.INSTANCE.NetUserAdd(null, 1, this.userInfo, null); + Assume.assumeThat("Unable to add user (need to be administrator to do this).", this.resultOfNetAddUser, + is(LMErr.NERR_Success)); + } + + /** + * Tear down. + */ + @After + public void tearDown() { + this.filter.destroy(); + + if (LMErr.NERR_Success == this.resultOfNetAddUser) { + Assert.assertEquals(LMErr.NERR_Success, + Netapi32.INSTANCE.NetUserDel(null, this.userInfo.usri1_name.toString())); + } + } + + /** + * Test impersonate enabled. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + @Test + public void testImpersonateEnabled() throws IOException, ServletException { + + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Current user shouldn't be the test user prior to the test"); + + final SimpleHttpRequest request = new SimpleHttpRequest(); + request.setMethod("GET"); + final String userHeaderValue = MockWindowsAccount.TEST_USER_NAME + ":" + MockWindowsAccount.TEST_PASSWORD; + final String basicAuthHeader = "Basic " + + BaseEncoding.base64().encode(userHeaderValue.getBytes(Charsets.UTF_8)); + request.addHeader("Authorization", basicAuthHeader); + + final SimpleHttpResponse response = new SimpleHttpResponse(); + final RecordUserNameFilterChain filterChain = new RecordUserNameFilterChain(); + + this.filter.setImpersonate(true); + this.filter.doFilter(request, response, filterChain); + + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Assert.assertTrue("Test user should be authenticated", authentication.isAuthenticated()); + + final Principal principal = (Principal) authentication.getPrincipal(); + assertThat(principal).isInstanceOf(AutoDisposableWindowsPrincipal.class); + AutoDisposableWindowsPrincipal windowsPrincipal = (AutoDisposableWindowsPrincipal) principal; + try { + assertThat(filterChain.getUserName()) + .isEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Test user should be impersonated"); + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Impersonation context should have been reverted"); + } finally { + windowsPrincipal.getIdentity().dispose(); + } + } + + /** + * Test impersonate disabled. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + @Test + public void testImpersonateDisabled() throws IOException, ServletException { + + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Current user shouldn't be the test user prior to the test"); + final SimpleHttpRequest request = new SimpleHttpRequest(); + request.setMethod("GET"); + final String userHeaderValue = MockWindowsAccount.TEST_USER_NAME + ":" + MockWindowsAccount.TEST_PASSWORD; + final String basicAuthHeader = "Basic " + + BaseEncoding.base64().encode(userHeaderValue.getBytes(Charsets.UTF_8)); + request.addHeader("Authorization", basicAuthHeader); + final SimpleHttpResponse response = new SimpleHttpResponse(); + final RecordUserNameFilterChain filterChain = new RecordUserNameFilterChain(); + + this.filter.setImpersonate(false); + this.filter.doFilter(request, response, filterChain); + + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Assert.assertTrue("Test user should be authenticated", authentication.isAuthenticated()); + + final Principal principal = (Principal) authentication.getPrincipal(); + assertThat(principal).isInstanceOf(WindowsPrincipal.class); + WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; + try { + assertThat(filterChain.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Test user should not be impersonated"); + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Impersonation context should have been reverted"); + } finally { + windowsPrincipal.getIdentity().dispose(); + } + } +} diff --git a/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java index 3d90ca1501..84e90a6cdb 100644 --- a/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java +++ b/Source/JNA/waffle-spring-security4/src/main/java/waffle/spring/NegotiateSecurityFilter.java @@ -30,10 +30,12 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; +import waffle.servlet.AutoDisposableWindowsPrincipal; import waffle.servlet.WindowsPrincipal; import waffle.servlet.spi.SecurityFilterProviderCollection; import waffle.util.AuthorizationHeader; import waffle.windows.auth.IWindowsIdentity; +import waffle.windows.auth.IWindowsImpersonationContext; import waffle.windows.auth.PrincipalFormat; /** @@ -59,6 +61,9 @@ public class NegotiateSecurityFilter extends GenericFilterBean { /** The allow guest login. */ private boolean allowGuestLogin = true; + /** The impersonate. */ + private boolean impersonate; + /** The granted authority factory. */ private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY; @@ -115,12 +120,14 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final return; } + IWindowsImpersonationContext ctx = null; try { NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString()); - final WindowsPrincipal principal = new WindowsPrincipal(windowsIdentity, this.principalFormat, - this.roleFormat); + final WindowsPrincipal principal = impersonate ? new AutoDisposableWindowsPrincipal(windowsIdentity, + this.principalFormat, this.roleFormat) : new WindowsPrincipal(windowsIdentity, + this.principalFormat, this.roleFormat); NegotiateSecurityFilter.LOGGER.debug("roles: {}", principal.getRolesString()); @@ -133,12 +140,23 @@ public void doFilter(final ServletRequest req, final ServletResponse res, final NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn()); + if (this.impersonate) { + LOGGER.debug("impersonating user"); + ctx = windowsIdentity.impersonate(); + } + + chain.doFilter(request, response); } finally { - windowsIdentity.dispose(); + if (this.impersonate && ctx != null) { + NegotiateSecurityFilter.LOGGER.debug("terminating impersonation"); + ctx.revertToSelf(); + } else { + windowsIdentity.dispose(); + } } + } else { + chain.doFilter(request, response); } - - chain.doFilter(request, response); } /* @@ -276,6 +294,25 @@ public void setAllowGuestLogin(final boolean value) { this.allowGuestLogin = value; } + /** + * Enable/Disable impersonation. + * + * @param value + * true to enable impersonation, false otherwise + */ + public void setImpersonate(final boolean value) { + this.impersonate = value; + } + + /** + * Checks if is impersonate. + * + * @return true if impersonation is enabled, false otherwise + */ + public boolean isImpersonate() { + return this.impersonate; + } + /** * Gets the provider. * diff --git a/Source/JNA/waffle-spring-security4/src/test/java/waffle/spring/ImpersonateTests.java b/Source/JNA/waffle-spring-security4/src/test/java/waffle/spring/ImpersonateTests.java new file mode 100644 index 0000000000..695d680819 --- /dev/null +++ b/Source/JNA/waffle-spring-security4/src/test/java/waffle/spring/ImpersonateTests.java @@ -0,0 +1,180 @@ +/** + * Waffle (https://github.com/dblock/waffle) + * + * Copyright (c) 2010 - 2015 Application Security, Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Application Security, Inc. + */ +package waffle.spring; + +import com.google.common.base.Charsets; +import com.google.common.io.BaseEncoding; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Advapi32Util; +import com.sun.jna.platform.win32.LMAccess; +import com.sun.jna.platform.win32.LMErr; +import com.sun.jna.platform.win32.Netapi32; +import org.junit.After; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import waffle.mock.MockWindowsAccount; +import waffle.mock.http.RecordUserNameFilterChain; +import waffle.mock.http.SimpleHttpRequest; +import waffle.mock.http.SimpleHttpResponse; +import waffle.servlet.AutoDisposableWindowsPrincipal; +import waffle.servlet.WindowsPrincipal; +import waffle.servlet.spi.SecurityFilterProviderCollection; +import waffle.windows.auth.impl.WindowsAuthProviderImpl; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.security.Principal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.is; + +/** + * The Class ImpersonateTests. + */ +public class ImpersonateTests { + + /** The filter. */ + private waffle.spring.NegotiateSecurityFilter filter; + + /** The user info. */ + private LMAccess.USER_INFO_1 userInfo; + + /** The result of net add user. */ + private int resultOfNetAddUser; + + /** + * Sets the up. + */ + @Before + public void setUp() { + this.filter = new NegotiateSecurityFilter(); + this.filter.setProvider(new SecurityFilterProviderCollection(new WindowsAuthProviderImpl())); + + this.userInfo = new LMAccess.USER_INFO_1(); + this.userInfo.usri1_name = new WString(MockWindowsAccount.TEST_USER_NAME); + this.userInfo.usri1_password = new WString(MockWindowsAccount.TEST_PASSWORD); + this.userInfo.usri1_priv = LMAccess.USER_PRIV_USER; + + this.resultOfNetAddUser = Netapi32.INSTANCE.NetUserAdd(null, 1, this.userInfo, null); + Assume.assumeThat("Unable to add user (need to be administrator to do this).", this.resultOfNetAddUser, + is(LMErr.NERR_Success)); + } + + /** + * Tear down. + */ + @After + public void tearDown() { + this.filter.destroy(); + + if (LMErr.NERR_Success == this.resultOfNetAddUser) { + Assert.assertEquals(LMErr.NERR_Success, + Netapi32.INSTANCE.NetUserDel(null, this.userInfo.usri1_name.toString())); + } + } + + /** + * Test impersonate enabled. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + @Test + public void testImpersonateEnabled() throws IOException, ServletException { + + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Current user shouldn't be the test user prior to the test"); + + final SimpleHttpRequest request = new SimpleHttpRequest(); + request.setMethod("GET"); + final String userHeaderValue = MockWindowsAccount.TEST_USER_NAME + ":" + MockWindowsAccount.TEST_PASSWORD; + final String basicAuthHeader = "Basic " + + BaseEncoding.base64().encode(userHeaderValue.getBytes(Charsets.UTF_8)); + request.addHeader("Authorization", basicAuthHeader); + + final SimpleHttpResponse response = new SimpleHttpResponse(); + final RecordUserNameFilterChain filterChain = new RecordUserNameFilterChain(); + + this.filter.setImpersonate(true); + this.filter.doFilter(request, response, filterChain); + + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Assert.assertTrue("Test user should be authenticated", authentication.isAuthenticated()); + + final Principal principal = (Principal) authentication.getPrincipal(); + assertThat(principal).isInstanceOf(AutoDisposableWindowsPrincipal.class); + AutoDisposableWindowsPrincipal windowsPrincipal = (AutoDisposableWindowsPrincipal) principal; + try { + assertThat(filterChain.getUserName()) + .isEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Test user should be impersonated"); + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Impersonation context should have been reverted"); + } finally { + windowsPrincipal.getIdentity().dispose(); + } + } + + /** + * Test impersonate disabled. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws ServletException + * the servlet exception + */ + @Test + public void testImpersonateDisabled() throws IOException, ServletException { + + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Current user shouldn't be the test user prior to the test"); + final SimpleHttpRequest request = new SimpleHttpRequest(); + request.setMethod("GET"); + final String userHeaderValue = MockWindowsAccount.TEST_USER_NAME + ":" + MockWindowsAccount.TEST_PASSWORD; + final String basicAuthHeader = "Basic " + + BaseEncoding.base64().encode(userHeaderValue.getBytes(Charsets.UTF_8)); + request.addHeader("Authorization", basicAuthHeader); + final SimpleHttpResponse response = new SimpleHttpResponse(); + final RecordUserNameFilterChain filterChain = new RecordUserNameFilterChain(); + + this.filter.setImpersonate(false); + this.filter.doFilter(request, response, filterChain); + + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Assert.assertTrue("Test user should be authenticated", authentication.isAuthenticated()); + + final Principal principal = (Principal) authentication.getPrincipal(); + assertThat(principal).isInstanceOf(WindowsPrincipal.class); + WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; + try { + assertThat(filterChain.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Test user should not be impersonated"); + assertThat(Advapi32Util.getUserName()) + .isNotEqualTo(MockWindowsAccount.TEST_USER_NAME) + .withFailMessage("Impersonation context should have been reverted"); + } finally { + windowsPrincipal.getIdentity().dispose(); + } + } +} diff --git a/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/RecordUserNameFilterChain.java b/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/RecordUserNameFilterChain.java new file mode 100644 index 0000000000..683d8a6efb --- /dev/null +++ b/Source/JNA/waffle-tests/src/main/java/waffle/mock/http/RecordUserNameFilterChain.java @@ -0,0 +1,50 @@ +/** + * Waffle (https://github.com/dblock/waffle) + * + * Copyright (c) 2010 - 2015 Application Security, Inc. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Application Security, Inc. + */ +package waffle.mock.http; + +import com.sun.jna.platform.win32.Advapi32Util; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +/** + * Filter chain that records current username. + */ +public class RecordUserNameFilterChain extends SimpleFilterChain { + + /** The user name. */ + private String userName; + + /* + * (non-Javadoc) + * @see waffle.mock.http.SimpleFilterChain#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + */ + @Override + public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse) + throws IOException, ServletException { + super.doFilter(servletRequest, servletResponse); + this.userName = Advapi32Util.getUserName(); + } + + /** + * Gets the user name. + * + * @return the user name + */ + public String getUserName() { + return this.userName; + } +} \ No newline at end of file diff --git a/Source/JNA/waffle-tests/src/test/java/waffle/servlet/ImpersonateTests.java b/Source/JNA/waffle-tests/src/test/java/waffle/servlet/ImpersonateTests.java index 2f1ac9051a..f8e506df91 100644 --- a/Source/JNA/waffle-tests/src/test/java/waffle/servlet/ImpersonateTests.java +++ b/Source/JNA/waffle-tests/src/test/java/waffle/servlet/ImpersonateTests.java @@ -36,6 +36,7 @@ import com.sun.jna.platform.win32.Netapi32; import waffle.mock.MockWindowsAccount; +import waffle.mock.http.RecordUserNameFilterChain; import waffle.mock.http.SimpleFilterChain; import waffle.mock.http.SimpleHttpRequest; import waffle.mock.http.SimpleHttpResponse; @@ -124,9 +125,6 @@ public void testImpersonateEnabled() throws IOException, ServletException { final boolean authenticated = subject != null && subject.getPrincipals().size() > 0; Assert.assertTrue("Test user should be authenticated", authenticated); - if (subject == null) { - return; - } final Principal principal = subject.getPrincipals().iterator().next(); Assert.assertTrue(principal instanceof AutoDisposableWindowsPrincipal); windowsPrincipal = (AutoDisposableWindowsPrincipal) principal; @@ -173,9 +171,6 @@ public void testImpersonateDisabled() throws IOException, ServletException { final boolean authenticated = subject != null && subject.getPrincipals().size() > 0; Assert.assertTrue("Test user should be authenticated", authenticated); - if (subject == null) { - return; - } final Principal principal = subject.getPrincipals().iterator().next(); Assert.assertTrue(principal instanceof WindowsPrincipal); windowsPrincipal = (WindowsPrincipal) principal; @@ -190,33 +185,4 @@ public void testImpersonateDisabled() throws IOException, ServletException { } } } - - /** - * Filter chain that records current username. - */ - public static class RecordUserNameFilterChain extends SimpleFilterChain { - - /** The user name. */ - private String userName; - - /* - * (non-Javadoc) - * @see waffle.mock.http.SimpleFilterChain#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse) - */ - @Override - public void doFilter(final ServletRequest sreq, final ServletResponse srep) throws IOException, - ServletException { - this.userName = Advapi32Util.getUserName(); - } - - /** - * Gets the user name. - * - * @return the user name - */ - public String getUserName() { - return this.userName; - } - } - }