|
@@ -28,8 +28,10 @@ import org.mockito.stubbing.Answer;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
|
|
import org.springframework.mock.web.MockServletContext;
|
|
|
+import org.springframework.security.authorization.AuthorizationManager;
|
|
|
import org.springframework.security.config.test.SpringTestContext;
|
|
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
|
|
+import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
|
|
import org.springframework.test.web.servlet.MockMvc;
|
|
|
import org.springframework.test.web.servlet.request.RequestPostProcessor;
|
|
|
import org.springframework.web.bind.annotation.PathVariable;
|
|
@@ -37,6 +39,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
|
|
|
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
import static org.mockito.BDDMockito.given;
|
|
|
import static org.mockito.Mockito.mock;
|
|
@@ -75,6 +78,23 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * sec-2256
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void requestWhenMethodIsSpecifiedAndAuthorizationManagerThenItIsNotGivenPriority() throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("Sec2256AuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(post("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* sec-2355
|
|
|
*/
|
|
@@ -91,6 +111,25 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * sec-2355
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingPatchAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("PatchMethodAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(patch("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ this.mvc.perform(patch("/path").with(adminCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void requestWhenUsingHasAnyRoleThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
this.spring.configLocations(this.xml("HasAnyRole")).autowire();
|
|
@@ -102,6 +141,20 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingHasAnyRoleAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("HasAnyRoleAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path").with(adminCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* sec-2059
|
|
|
*/
|
|
@@ -118,6 +171,26 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * sec-2059
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingPathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
|
|
|
+ throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("PathVariablesAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path/user/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ this.mvc.perform(get("/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* gh-3786
|
|
|
*/
|
|
@@ -134,6 +207,26 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * gh-3786
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingCamelCasePathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
|
|
|
+ throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("CamelCasePathVariablesAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path/user/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ this.mvc.perform(get("/PATH/user/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* sec-2059
|
|
|
*/
|
|
@@ -148,6 +241,24 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * sec-2059
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingPathVariablesAndTypeConversionAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
|
|
|
+ throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("TypeConversionPathVariablesAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path/1/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path/2/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void requestWhenUsingMvcMatchersThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
this.spring.configLocations(this.xml("MvcMatchers")).autowire();
|
|
@@ -156,6 +267,17 @@ public class InterceptUrlConfigTests {
|
|
|
this.mvc.perform(get("/path/")).andExpect(status().isUnauthorized());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingMvcMatchersAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("MvcMatchersAuthorizationManager")).autowire();
|
|
|
+ this.mvc.perform(get("/path")).andExpect(status().isUnauthorized());
|
|
|
+ this.mvc.perform(get("/path.html")).andExpect(status().isUnauthorized());
|
|
|
+ this.mvc.perform(get("/path/")).andExpect(status().isUnauthorized());
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void requestWhenUsingMvcMatchersAndPathVariablesThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
this.spring.configLocations(this.xml("MvcMatchersPathVariables")).autowire();
|
|
@@ -169,6 +291,23 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingMvcMatchersAndPathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
|
|
|
+ throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("MvcMatchersPathVariablesAuthorizationManager")).autowire();
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/path/user/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isOk());
|
|
|
+ this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ this.mvc.perform(get("/PATH/user/path").with(userCredentials()))
|
|
|
+ .andExpect(status().isForbidden());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void requestWhenUsingMvcMatchersAndServletPathThenAuthorizesRequestsAccordingly() throws Exception {
|
|
|
this.spring.configLocations(this.xml("MvcMatchersServletPath")).autowire();
|
|
@@ -185,30 +324,74 @@ public class InterceptUrlConfigTests {
|
|
|
// @formatter:on
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void requestWhenUsingMvcMatchersAndServletPathAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
|
|
|
+ throws Exception {
|
|
|
+ this.spring.configLocations(this.xml("MvcMatchersServletPathAuthorizationManager")).autowire();
|
|
|
+ MockServletContext servletContext = mockServletContext("/spring");
|
|
|
+ ConfigurableWebApplicationContext context = this.spring.getContext();
|
|
|
+ context.setServletContext(servletContext);
|
|
|
+ // @formatter:off
|
|
|
+ this.mvc.perform(get("/spring/path").servletPath("/spring"))
|
|
|
+ .andExpect(status().isUnauthorized());
|
|
|
+ this.mvc.perform(get("/spring/path.html").servletPath("/spring"))
|
|
|
+ .andExpect(status().isUnauthorized());
|
|
|
+ this.mvc.perform(get("/spring/path/").servletPath("/spring"))
|
|
|
+ .andExpect(status().isUnauthorized());
|
|
|
+ // @formatter:on
|
|
|
+ assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
|
|
|
+ .isEmpty();
|
|
|
+ assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void configureWhenUsingAntMatcherAndServletPathThenThrowsException() {
|
|
|
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
|
|
.isThrownBy(() -> this.spring.configLocations(this.xml("AntMatcherServletPath")).autowire());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void configureWhenUsingAntMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
|
|
|
+ assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(
|
|
|
+ () -> this.spring.configLocations(this.xml("AntMatcherServletPathAuthorizationManager")).autowire());
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void configureWhenUsingRegexMatcherAndServletPathThenThrowsException() {
|
|
|
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
|
|
.isThrownBy(() -> this.spring.configLocations(this.xml("RegexMatcherServletPath")).autowire());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void configureWhenUsingRegexMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
|
|
|
+ assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(
|
|
|
+ () -> this.spring.configLocations(this.xml("RegexMatcherServletPathAuthorizationManager")).autowire());
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void configureWhenUsingCiRegexMatcherAndServletPathThenThrowsException() {
|
|
|
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
|
|
.isThrownBy(() -> this.spring.configLocations(this.xml("CiRegexMatcherServletPath")).autowire());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void configureWhenUsingCiRegexMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
|
|
|
+ assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> this.spring
|
|
|
+ .configLocations(this.xml("CiRegexMatcherServletPathAuthorizationManager")).autowire());
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void configureWhenUsingDefaultMatcherAndServletPathThenThrowsException() {
|
|
|
assertThatExceptionOfType(BeanDefinitionParsingException.class)
|
|
|
.isThrownBy(() -> this.spring.configLocations(this.xml("DefaultMatcherServletPath")).autowire());
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void configureWhenUsingDefaultMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
|
|
|
+ assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> this.spring
|
|
|
+ .configLocations(this.xml("DefaultMatcherServletPathAuthorizationManager")).autowire());
|
|
|
+ }
|
|
|
+
|
|
|
private static RequestPostProcessor adminCredentials() {
|
|
|
return httpBasic("admin", "password");
|
|
|
}
|