Add no-parameter authorizeHttpRequests method

Closes gh-9498
This commit is contained in:
sdratler1 2021-04-12 20:08:09 +03:00 committed by Josh Cummings
parent 0080aeee94
commit 3820f0f3a3
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
2 changed files with 133 additions and 1 deletions

View File

@ -1320,7 +1320,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
* &#064;Configuration * &#064;Configuration
* &#064;EnableWebSecurity * &#064;EnableWebSecurity
* public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter { * public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter {
* *HttpSecurity.java
* &#064;Override * &#064;Override
* protected void configure(HttpSecurity http) throws Exception { * protected void configure(HttpSecurity http) throws Exception {
* http * http
@ -1348,6 +1348,86 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
return HttpSecurity.this; return HttpSecurity.this;
} }
/**
* Allows restricting access based upon the {@link HttpServletRequest} using
* {@link RequestMatcher} implementations (i.e. via URL patterns).
*
* <h2>Example Configurations</h2>
*
* The most basic example is to configure all URLs to require the role "ROLE_USER".
* The configuration below requires authentication to every URL and will grant access
* to both the user "admin" and "user".
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .authorizeHttpRequests()
* .antMatchers(&quot;/**&quot;).hasRoles(&quot;USER&quot;)
* .and()
* .formLogin();
* }
* }
* </pre>
*
* We can also configure multiple URLs. The configuration below requires
* authentication to every URL and will grant access to URLs starting with /admin/ to
* only the "admin" user. All other URLs either user can access.
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .authorizeHttpRequests()
* .antMatchers(&quot;/**&quot;).hasRoles(&quot;USER&quot;)
* .and()
* .formLogin();
* .formLogin(withDefaults());
* }
* }
* </pre>
*
* Note that the matchers are considered in order. Therefore, the following is invalid
* because the first matcher matches every request and will never get to the second
* mapping:
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class AuthorizeUrlsSecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .authorizeHttpRequests()
* .antMatchers(&quot;/**&quot;).hasRoles(&quot;USER&quot;)
* .and()
* .formLogin();
* }
* }
* </pre>
* @return the {@link HttpSecurity} for further customizations
* @throws Exception
* @since 5.5
* @see #requestMatcher(RequestMatcher)
*/
public HttpSecurity authorizeHttpRequests() throws Exception {
ApplicationContext applicationContext = getContext();
Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry> authorizeHttpRequestsCustomizer = Customizer
.withDefaults();
authorizeHttpRequestsCustomizer
.customize(getOrApply(new AuthorizeHttpRequestsConfigurer<>(applicationContext)).getRegistry());
return HttpSecurity.this;
}
/** /**
* Allows configuring the Request Cache. For example, a protected page (/protected) * Allows configuring the Request Cache. For example, a protected page (/protected)
* may be requested prior to authentication. The application will redirect the user to * may be requested prior to authentication. The application will redirect the user to

View File

@ -72,6 +72,14 @@ public class AuthorizeHttpRequestsConfigurerTests {
"At least one mapping is required (for example, authorizeHttpRequests().anyRequest().authenticated())"); "At least one mapping is required (for example, authorizeHttpRequests().anyRequest().authenticated())");
} }
@Test
public void configureWhenAuthorizedHttpRequestsAndNoRequestsThenExceptionWithDefaultConfig() {
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> this.spring.register(NoRequestsConfigWithDefaultConfig.class).autowire())
.withMessageContaining(
"At least one mapping is required (for example, authorizeHttpRequests().anyRequest().authenticated())");
}
@Test @Test
public void configureWhenAnyRequestIncompleteMappingThenException() { public void configureWhenAnyRequestIncompleteMappingThenException() {
assertThatExceptionOfType(BeanCreationException.class) assertThatExceptionOfType(BeanCreationException.class)
@ -79,6 +87,14 @@ public class AuthorizeHttpRequestsConfigurerTests {
.withMessageContaining("An incomplete mapping was found for "); .withMessageContaining("An incomplete mapping was found for ");
} }
@Test
public void configureWhenAnyRequestIncompleteMappingDefaultConfigThenException() {
assertThatExceptionOfType(BeanCreationException.class)
this.spring.register(IncompleteMappingConfigWithDefaultConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isOk());
verify(CustomAuthorizationManagerConfig.authorizationManager).check(any(), any());
}
@Test @Test
public void configureWhenMvcMatcherAfterAnyRequestThenException() { public void configureWhenMvcMatcherAfterAnyRequestThenException() {
assertThatExceptionOfType(BeanCreationException.class) assertThatExceptionOfType(BeanCreationException.class)
@ -94,6 +110,14 @@ public class AuthorizeHttpRequestsConfigurerTests {
verify(CustomAuthorizationManagerConfig.authorizationManager).check(any(), any()); verify(CustomAuthorizationManagerConfig.authorizationManager).check(any(), any());
} }
@Test
public void configureMvcMatcherAccessAuthorizationManagerOnDefault() throws Exception {
CustomAuthorizationManagerConfig.authorizationManager = mock(AuthorizationManager.class);
this.spring.register(IncompleteMappingConfigWithDefaultConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
verify(CustomAuthorizationManagerConfig.authorizationManager).check(any(), any());
}
@Test @Test
public void configureMvcMatcherAccessAuthorizationManagerWhenNullThenException() { public void configureMvcMatcherAccessAuthorizationManagerWhenNullThenException() {
CustomAuthorizationManagerConfig.authorizationManager = null; CustomAuthorizationManagerConfig.authorizationManager = null;
@ -370,6 +394,34 @@ public class AuthorizeHttpRequestsConfigurerTests {
} }
@EnableWebSecurity
static class NoRequestsConfigWithDefaultConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
return http
.authorizeHttpRequests()
.build();
// @formatter:on
}
}
@EnableWebSecurity
static class IncompleteMappingConfigWithDefaultConfig {
@Bean
FormLoginConfigurer<HttpSecurity> filterChain(HttpSecurity http) throws Exception {
// @formatter:off
return http
.authorizeHttpRequests()
.formLogin();
// @formatter:on
}
}
@EnableWebSecurity @EnableWebSecurity
static class IncompleteMappingConfig { static class IncompleteMappingConfig {