/* * Copyright 2002-2016 the original author or authors. * * 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.springframework.security.config.http; import org.junit.After; import org.junit.Test; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.support.AbstractXmlApplicationContext; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.config.BeanIds; import org.springframework.security.config.ConfigTestUtils; import org.springframework.security.config.util.InMemoryXmlApplicationContext; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource; import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; import java.util.Collection; import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link FilterInvocationSecurityMetadataSourceParser}. * * @author Luke Taylor */ public class FilterSecurityMetadataSourceBeanDefinitionParserTests { private AbstractXmlApplicationContext appContext; @After public void closeAppContext() { if (this.appContext != null) { this.appContext.close(); this.appContext = null; } } private void setContext(String context) { this.appContext = new InMemoryXmlApplicationContext(context); } @Test public void parsingMinimalConfigurationIsSuccessful() { setContext("<filter-security-metadata-source id='fids' use-expressions='false'>" + " <intercept-url pattern='/**' access='ROLE_A'/>" + "</filter-security-metadata-source>"); DefaultFilterInvocationSecurityMetadataSource fids = (DefaultFilterInvocationSecurityMetadataSource) this.appContext .getBean("fids"); Collection<ConfigAttribute> cad = fids .getAttributes(createFilterInvocation("/anything", "GET")); assertThat(cad).isNotNull(); assertThat(cad.contains(new SecurityConfig("ROLE_A"))).isTrue(); } @Test public void expressionsAreSupported() { setContext("<filter-security-metadata-source id='fids'>" + " <intercept-url pattern='/**' access=\"hasRole('ROLE_A')\" />" + "</filter-security-metadata-source>"); ExpressionBasedFilterInvocationSecurityMetadataSource fids = (ExpressionBasedFilterInvocationSecurityMetadataSource) this.appContext .getBean("fids"); ConfigAttribute[] cad = fids .getAttributes(createFilterInvocation("/anything", "GET")) .toArray(new ConfigAttribute[0]); assertThat(cad.length).isEqualTo(1); assertThat(cad[0].toString()).isEqualTo("hasRole('ROLE_A')"); } // SEC-1201 @Test public void interceptUrlsSupportPropertyPlaceholders() { System.setProperty("secure.url", "/secure"); System.setProperty("secure.role", "ROLE_A"); setContext( "<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" + "<filter-security-metadata-source id='fids' use-expressions='false'>" + " <intercept-url pattern='${secure.url}' access='${secure.role}'/>" + "</filter-security-metadata-source>"); DefaultFilterInvocationSecurityMetadataSource fids = (DefaultFilterInvocationSecurityMetadataSource) this.appContext .getBean("fids"); Collection<ConfigAttribute> cad = fids .getAttributes(createFilterInvocation("/secure", "GET")); assertThat(cad).isNotNull(); assertThat(cad).hasSize(1); assertThat(cad.contains(new SecurityConfig("ROLE_A"))).isTrue(); } @Test public void parsingWithinFilterSecurityInterceptorIsSuccessful() { setContext("<http auto-config='true' use-expressions='false'/>" + "<b:bean id='fsi' class='org.springframework.security.web.access.intercept.FilterSecurityInterceptor' autowire='byType'>" + " <b:property name='securityMetadataSource'>" + " <filter-security-metadata-source use-expressions='false'>" + " <intercept-url pattern='/secure/extreme/**' access='ROLE_SUPERVISOR'/>" + " <intercept-url pattern='/secure/**' access='ROLE_USER'/>" + " <intercept-url pattern='/**' access='ROLE_USER'/>" + " </filter-security-metadata-source>" + " </b:property>" + " <b:property name='authenticationManager' ref='" + BeanIds.AUTHENTICATION_MANAGER + "'/>" + "</b:bean>" + ConfigTestUtils.AUTH_PROVIDER_XML); } @Test(expected = BeanDefinitionParsingException.class) public void parsingInterceptUrlServletPathFails() { setContext("<filter-security-metadata-source id='fids' use-expressions='false'>" + " <intercept-url pattern='/secure' access='ROLE_USER' servlet-path='/spring' />" + "</filter-security-metadata-source>"); } private FilterInvocation createFilterInvocation(String path, String method) { MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI(null); request.setMethod(method); request.setServletPath(path); return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain()); } }