Add PathRequest to reactive security for parity

This commit is contained in:
Madhura Bhave 2018-01-29 18:19:04 -08:00
parent e80c22cbf8
commit 134628a62d
6 changed files with 114 additions and 22 deletions

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012-2018 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.boot.autoconfigure.security.reactive;
import org.springframework.boot.autoconfigure.security.StaticResourceLocation;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
/**
* Factory that can be used to create a {@link ServerWebExchangeMatcher} for commonly used paths.
*
* @author Madhura Bhave
* @since 2.0.0
*/
public final class PathRequest {
private PathRequest() {
}
/**
* Returns a {@link StaticResourceRequest} that can be used to create a matcher for
* {@link StaticResourceLocation Locations}.
* @return a {@link StaticResourceRequest}
*/
public static StaticResourceRequest toStaticResources() {
return StaticResourceRequest.get();
}
}

View File

@ -33,14 +33,17 @@ import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
/**
* Factory that can be used to create a {@link ServerWebExchangeMatcher} for static
* resources in commonly used locations.
* Used to create a {@link ServerWebExchangeMatcher} for static resources in
* commonly used locations. Returned by {@link PathRequest#toStaticResources()}.
*
* @author Madhura Bhave
* @since 2.0.0
* @see PathRequest
*/
public final class StaticResourceRequest {
private static final StaticResourceRequest INSTANCE = new StaticResourceRequest();
private StaticResourceRequest() {
}
@ -50,42 +53,50 @@ public final class StaticResourceRequest {
* {@link StaticResourceServerWebExchange#excluding(StaticResourceLocation, StaticResourceLocation...)
* excluding} method can be used to remove specific locations if required. For
* example: <pre class="code">
* StaticResourceRequest.toCommonLocations().excluding(StaticResourceLocation.CSS)
* StaticResourceRequest.atCommonLocations().excluding(StaticResourceLocation.CSS)
* </pre>
* @return the configured {@link ServerWebExchangeMatcher}
*/
public static StaticResourceServerWebExchange toCommonLocations() {
return to(EnumSet.allOf(StaticResourceLocation.class));
public StaticResourceServerWebExchange atCommonLocations() {
return at(EnumSet.allOf(StaticResourceLocation.class));
}
/**
* Returns a matcher that includes the specified {@link StaticResourceLocation
* Locations}. For example: <pre class="code">
* to(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
* at(StaticResourceLocation.CSS, StaticResourceLocation.JAVA_SCRIPT)
* </pre>
* @param first the first location to include
* @param rest additional locations to include
* @return the configured {@link ServerWebExchangeMatcher}
*/
public static StaticResourceServerWebExchange to(StaticResourceLocation first,
public StaticResourceServerWebExchange at(StaticResourceLocation first,
StaticResourceLocation... rest) {
return to(EnumSet.of(first, rest));
return at(EnumSet.of(first, rest));
}
/**
* Returns a matcher that includes the specified {@link StaticResourceLocation
* Locations}. For example: <pre class="code">
* to(locations)
* at(locations)
* </pre>
* @param locations the locations to include
* @return the configured {@link ServerWebExchangeMatcher}
*/
public static StaticResourceServerWebExchange to(
public StaticResourceServerWebExchange at(
Set<StaticResourceLocation> locations) {
Assert.notNull(locations, "Locations must not be null");
return new StaticResourceServerWebExchange(new LinkedHashSet<>(locations));
}
/**
* Return the static resource request.
* @return the static resource request
*/
static StaticResourceRequest get() {
return INSTANCE;
}
/**
* The server web exchange matcher used to match against resource
* {@link StaticResourceLocation Locations}.

View File

@ -0,0 +1,35 @@
/*
* Copyright 2012-2018 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.boot.autoconfigure.security.reactive;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PathRequest}.
*
* @author Madhura Bhave
*/
public class PathRequestTests {
@Test
public void toStaticResourcesShouldReturnStaticResourceRequest() {
assertThat(PathRequest.toStaticResources()).isInstanceOf(StaticResourceRequest.class);
}
}

View File

@ -44,12 +44,14 @@ import static org.mockito.Mockito.mock;
*/
public class StaticResourceRequestTests {
private StaticResourceRequest resourceRequest = StaticResourceRequest.get();
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void toCommonLocationsShouldMatchCommonLocations() {
ServerWebExchangeMatcher matcher = StaticResourceRequest.toCommonLocations();
public void atCommonLocationsShouldMatchCommonLocations() {
ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations();
assertMatcher(matcher).matches("/css/file.css");
assertMatcher(matcher).matches("/js/file.js");
assertMatcher(matcher).matches("/images/file.css");
@ -59,33 +61,33 @@ public class StaticResourceRequestTests {
}
@Test
public void toCommonLocationsWithExcludeShouldNotMatchExcluded() {
ServerWebExchangeMatcher matcher = StaticResourceRequest.toCommonLocations()
public void atCommonLocationsWithExcludeShouldNotMatchExcluded() {
ServerWebExchangeMatcher matcher = this.resourceRequest.atCommonLocations()
.excluding(StaticResourceLocation.CSS);
assertMatcher(matcher).doesNotMatch("/css/file.css");
assertMatcher(matcher).matches("/js/file.js");
}
@Test
public void toLocationShouldMatchLocation() {
ServerWebExchangeMatcher matcher = StaticResourceRequest
.to(StaticResourceLocation.CSS);
public void atLocationShouldMatchLocation() {
ServerWebExchangeMatcher matcher = this.resourceRequest
.at(StaticResourceLocation.CSS);
assertMatcher(matcher).matches("/css/file.css");
assertMatcher(matcher).doesNotMatch("/js/file.js");
}
@Test
public void toLocationsFromSetWhenSetIsNullShouldThrowException() {
public void atLocationsFromSetWhenSetIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Locations must not be null");
StaticResourceRequest.to(null);
this.resourceRequest.at(null);
}
@Test
public void excludeFromSetWhenSetIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Locations must not be null");
StaticResourceRequest.toCommonLocations().excluding(null);
this.resourceRequest.atCommonLocations().excluding(null);
}
private StaticResourceRequestTests.RequestMatcherAssert assertMatcher(

View File

@ -3035,7 +3035,7 @@ Boot provides convenience methods that can be used to override access rules for
endpoints and static resources. `EndpointRequest` can be used to create a `ServerWebExchangeMatcher`
that is based on the `management.endpoints.web.base-path` property.
`StaticResourceRequest` can be used to create a `ServerWebExchangeMatcher` for static resources in
`PathRequest` can be used to create a `ServerWebExchangeMatcher` for resources in
commonly used locations.

View File

@ -23,6 +23,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest;
import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
import org.springframework.boot.autoconfigure.security.reactive.StaticResourceRequest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
@ -101,7 +102,7 @@ public class SampleSecureWebFluxCustomSecurityTests {
http.authorizeExchange().matchers(EndpointRequest.to("health", "info"))
.permitAll().matchers(EndpointRequest.toAnyEndpoint())
.hasRole("ACTUATOR")
.matchers(StaticResourceRequest.toCommonLocations()).permitAll()
.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.pathMatchers("/login").permitAll().anyExchange().authenticated()
.and().httpBasic();
return http.build();