/*
* Copyright 2015 herd contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.finra.herd.app.security;
import static org.junit.Assert.assertNull;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.finra.herd.app.AbstractAppTest;
import org.finra.herd.model.api.xml.NamespaceAuthorization;
import org.finra.herd.model.dto.ConfigurationValue;
import org.finra.herd.model.jpa.SecurityFunctionEntity;
import org.finra.herd.model.jpa.SecurityRoleEntity;
import org.finra.herd.model.jpa.SecurityRoleFunctionEntity;
/**
* This class tests the http header authentication filter.
*/
public class HttpHeaderAuthenticationFilterTest extends AbstractAppTest
{
private final String[] TEST_FUNCTIONS = {"test_function_1", "test_function_2"};
@Test
public void testHttpHeaderAuthenticationFilter() throws Exception
{
setupTestFunctions("testRole");
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
null);
// retry with same request.
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterRegularUser() throws Exception
{
// Create and persist the relative database entities.
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE);
userNamespaceAuthorizationDaoTestHelper
.createUserNamespaceAuthorizationEntity(USER_ID, namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE_2), SUPPORTED_NAMESPACE_PERMISSIONS);
userNamespaceAuthorizationDaoTestHelper
.createUserNamespaceAuthorizationEntity(USER_ID, namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE_3), SUPPORTED_NAMESPACE_PERMISSIONS);
// Create an ordered set of expected namespace authorizations.
Set<NamespaceAuthorization> expectedNamespaceAuthorizations = new HashSet<>();
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE_2, SUPPORTED_NAMESPACE_PERMISSIONS));
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE_3, SUPPORTED_NAMESPACE_PERMISSIONS));
setupTestFunctions("testRole");
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
// retry with same request.
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterAdminUser() throws Exception
{
// Create and persist the relative database entities.
userDaoTestHelper.createUserEntity(USER_ID, true);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE_2);
// Create an ordered set of expected namespace authorizations.
Set<NamespaceAuthorization> expectedNamespaceAuthorizations = new HashSet<>();
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE, SUPPORTED_NAMESPACE_PERMISSIONS));
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE_2, SUPPORTED_NAMESPACE_PERMISSIONS));
setupTestFunctions("testRole");
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
// retry with same request.
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterUserAuthorizationDisabled() throws Exception
{
// Create and persist the relative database entities.
userDaoTestHelper.createUserEntity(USER_ID, true);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE_2);
// Create an ordered set of expected namespace authorizations.
Set<NamespaceAuthorization> expectedNamespaceAuthorizations = new HashSet<>();
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE, SUPPORTED_NAMESPACE_PERMISSIONS));
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE_2, SUPPORTED_NAMESPACE_PERMISSIONS));
setupTestFunctions("testRole");
Map<String, Object> overrideMap = getDefaultSecurityEnvironmentVariables();
overrideMap.put(ConfigurationValue.USER_NAMESPACE_AUTHORIZATION_ENABLED.getKey(), "false");
modifyPropertySourceInEnvironment(overrideMap);
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
// retry with same request.
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", TEST_FUNCTIONS,
expectedNamespaceAuthorizations);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterUserAuthorizationInvalidConfigurationValue() throws Exception
{
// Create and persist the relative database entities.
userDaoTestHelper.createUserEntity(USER_ID, true);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE);
namespaceDaoTestHelper.createNamespaceEntity(NAMESPACE_2);
// Create an ordered set of expected namespace authorizations.
Set<NamespaceAuthorization> expectedNamespaceAuthorizations = new HashSet<>();
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE, SUPPORTED_NAMESPACE_PERMISSIONS));
expectedNamespaceAuthorizations.add(new NamespaceAuthorization(NAMESPACE_2, SUPPORTED_NAMESPACE_PERMISSIONS));
setupTestFunctions("testRole");
Map<String, Object> overrideMap = getDefaultSecurityEnvironmentVariables();
overrideMap.put(ConfigurationValue.USER_NAMESPACE_AUTHORIZATION_ENABLED.getKey(), "NOT_A_BOOLEAN");
modifyPropertySourceInEnvironment(overrideMap);
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
// Validate that there is no authentication.
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterNoHeaders() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
// Invalidate user session if exists.
invalidateApplicationUser(null);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain());
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
assertNull(authentication);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterUserChangedInHeaders() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", null, null);
// Change the userId in the header.
request = getRequestWithHeaders(USER_ID_2, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID_2, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", null, null);
// Change the session init time in the header.
request = getRequestWithHeaders(USER_ID_2, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 11:24:09");
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID_2, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 11:24:09", null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterNoRoles() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request = getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", null, "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", (String) null, "Wed, 11 Mar 2015 10:24:09", null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterNoSessionInitTime() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request = getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", null, null);
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", (String) null, null, null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterInvalidateSessionOnWrongHeader() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09", null, null);
// Try again with no header, user should be invalidated.
httpHeaderAuthenticationFilter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain());
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
assertNull(authentication);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterMultipleRoles() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole1,testRole2", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
Set<String> expectedRoles = new HashSet<>();
expectedRoles.add("testRole1");
expectedRoles.add("testRole2");
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", expectedRoles, "Wed, 11 Mar 2015 10:24:09", null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterEmptyRoleRegex() throws Exception
{
Map<String, Object> overrideMap = getDefaultSecurityEnvironmentVariables();
overrideMap.put(ConfigurationValue.SECURITY_HTTP_HEADER_ROLE_REGEX.getKey(), " ");
modifyPropertySourceInEnvironment(overrideMap);
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole1,testRole2", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
Set<String> expectedRoles = new HashSet<>();
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", expectedRoles, "Wed, 11 Mar 2015 10:24:09", null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterNoRegexGroup() throws Exception
{
Map<String, Object> overrideMap = getDefaultSecurityEnvironmentVariables();
overrideMap.put(ConfigurationValue.SECURITY_HTTP_HEADER_ROLE_REGEX_GROUP.getKey(), " ");
modifyPropertySourceInEnvironment(overrideMap);
try
{
MockHttpServletRequest request =
getRequestWithHeaders(USER_ID, "testFirstName", "testLastName", "testEmail", "testRole1,testRole2", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
Set<String> expectedRoles = new HashSet<>();
expectedRoles.add("testRole1,");
expectedRoles.add("testRole2");
validateHttpHeaderApplicationUser(USER_ID, "testFirstName", "testLastName", "testEmail", expectedRoles, "Wed, 11 Mar 2015 10:24:09", null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
@Test
public void testHttpHeaderAuthenticationFilterUserIdWithDomainName() throws Exception
{
modifyPropertySourceInEnvironment(getDefaultSecurityEnvironmentVariables());
try
{
MockHttpServletRequest request =
getRequestWithHeaders("testUser@company.com", "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09");
// Invalidate user session if exists.
invalidateApplicationUser(request);
httpHeaderAuthenticationFilter.init(new MockFilterConfig());
httpHeaderAuthenticationFilter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
validateHttpHeaderApplicationUser("testUser@company.com", "testFirstName", "testLastName", "testEmail", "testRole", "Wed, 11 Mar 2015 10:24:09",
null, null);
}
finally
{
restorePropertySourceInEnvironment();
}
}
private void setupTestFunctions(String roleId)
{
SecurityRoleEntity securityRoleEntity = new SecurityRoleEntity();
securityRoleEntity.setCode(roleId);
herdDao.saveAndRefresh(securityRoleEntity);
for (String function : TEST_FUNCTIONS)
{
SecurityFunctionEntity securityFunctionEntity = new SecurityFunctionEntity();
securityFunctionEntity.setCode(function);
herdDao.saveAndRefresh(securityFunctionEntity);
SecurityRoleFunctionEntity securityRoleFunctionEntity = new SecurityRoleFunctionEntity();
securityRoleFunctionEntity.setSecurityRole(securityRoleEntity);
securityRoleFunctionEntity.setSecurityFunction(securityFunctionEntity);
herdDao.saveAndRefresh(securityRoleFunctionEntity);
}
}
}