Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b38b495630 | |||
| 5a7f12f1a9 | |||
| c614422f44 | |||
| 3656fa6e0c | |||
| 5b293d2116 | |||
| ff4745a461 | |||
| 38a7ffcc9b | |||
| d0491c07e9 | |||
| 486c5118d2 | |||
| 17d8293be1 | |||
| fe9bc26bdc | |||
| 7813a9ba26 | |||
| dc3cb68c76 | |||
| 56292c9971 | |||
| 4fc938555e | |||
| e574415244 | |||
| c5da886310 | |||
| 3bef5fd3ed | |||
| e7201c48d1 | |||
| 991b398c55 | |||
| 488b6ea531 | |||
| ef04ea9d68 | |||
| b7be4c462c | |||
| aa8440e1ee | |||
| 6d3f1699c0 |
@@ -4,6 +4,7 @@ import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
|
||||
|
||||
public class SchemaZipPlugin implements Plugin<Project> {
|
||||
|
||||
@@ -15,7 +16,10 @@ public class SchemaZipPlugin implements Plugin<Project> {
|
||||
schemaZip.archiveClassifier = 'schema'
|
||||
schemaZip.description = "Builds -${schemaZip.archiveClassifier} archive containing all " +
|
||||
"XSDs for deployment at static.springframework.org/schema."
|
||||
|
||||
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
|
||||
description = "Generates spring-security.xsd"
|
||||
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
|
||||
}
|
||||
project.rootProject.subprojects.each { module ->
|
||||
|
||||
module.getPlugins().withType(JavaPlugin.class).all {
|
||||
@@ -36,17 +40,14 @@ public class SchemaZipPlugin implements Plugin<Project> {
|
||||
duplicatesStrategy 'exclude'
|
||||
from xsdFile.path
|
||||
}
|
||||
}
|
||||
File symlink = module.sourceSets.main.resources.find {
|
||||
it.path.endsWith('org/springframework/security/config/spring-security.xsd')
|
||||
}
|
||||
if (symlink != null) {
|
||||
schemaZip.into('security') {
|
||||
duplicatesStrategy 'exclude'
|
||||
from symlink.path
|
||||
}
|
||||
versionlessXsd.getInputFiles().from(xsdFile.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
schemaZip.into("security") {
|
||||
from(versionlessXsd.getOutputs())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.gradle.sagan;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
@@ -25,6 +29,8 @@ import org.springframework.gradle.github.user.User;
|
||||
|
||||
public class SaganCreateReleaseTask extends DefaultTask {
|
||||
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-.+)?$");
|
||||
|
||||
@Input
|
||||
private String gitHubAccessToken;
|
||||
@Input
|
||||
@@ -44,9 +50,12 @@ public class SaganCreateReleaseTask extends DefaultTask {
|
||||
// Antora reference docs URLs for snapshots do not contain -SNAPSHOT
|
||||
String referenceDocUrl = this.referenceDocUrl;
|
||||
if (this.version.endsWith("-SNAPSHOT")) {
|
||||
referenceDocUrl = this.referenceDocUrl
|
||||
.replace("{version}", this.version)
|
||||
.replace("-SNAPSHOT", "");
|
||||
Matcher versionMatcher = VERSION_PATTERN.matcher(this.version);
|
||||
Assert.isTrue(versionMatcher.matches(), "Version " + this.version + " does not match expected pattern");
|
||||
String majorVersion = versionMatcher.group(1);
|
||||
String minorVersion = versionMatcher.group(2);
|
||||
String majorMinorVersion = String.format("%s.%s-SNAPSHOT", majorVersion, minorVersion);
|
||||
referenceDocUrl = this.referenceDocUrl.replace("{version}", majorMinorVersion);
|
||||
}
|
||||
|
||||
SaganApi sagan = new SaganApi(user.getLogin(), this.gitHubAccessToken);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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
|
||||
*
|
||||
* https://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.gradle.xsd;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.*;
|
||||
import org.gradle.work.DisableCachingByDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Creates the spring-security.xsd automatically
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@DisableCachingByDefault(because = "not worth it")
|
||||
public abstract class CreateVersionlessXsdTask extends DefaultTask {
|
||||
|
||||
@InputFiles
|
||||
public abstract ConfigurableFileCollection getInputFiles();
|
||||
|
||||
@OutputFile
|
||||
abstract RegularFileProperty getVersionlessXsdFile();
|
||||
|
||||
@TaskAction
|
||||
void createVersionlessXsd() throws IOException {
|
||||
XsdFileMajorMinorVersion largest = null;
|
||||
ConfigurableFileCollection inputFiles = getInputFiles();
|
||||
if (inputFiles.isEmpty()) {
|
||||
throw new IllegalStateException("No Inputs configured");
|
||||
}
|
||||
for (File file : inputFiles) {
|
||||
XsdFileMajorMinorVersion current = XsdFileMajorMinorVersion.create(file);
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
if (largest == null) {
|
||||
largest = current;
|
||||
}
|
||||
else if (current.getVersion().isGreaterThan(largest.getVersion())) {
|
||||
largest = current;
|
||||
}
|
||||
}
|
||||
if (largest == null) {
|
||||
throw new IllegalStateException("Could not create versionless xsd file because no files matching spring-security-<digit>.xsd were found in " + inputFiles.getFiles());
|
||||
}
|
||||
Path to = getVersionlessXsdFile().getAsFile().get().toPath();
|
||||
Path from = largest.getFile().toPath();
|
||||
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
static class XsdFileMajorMinorVersion {
|
||||
private final File file;
|
||||
|
||||
private final MajorMinorVersion version;
|
||||
|
||||
private XsdFileMajorMinorVersion(File file, MajorMinorVersion version) {
|
||||
this.file = file;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
private static final Pattern FILE_MAJOR_MINOR_VERSION_PATTERN = Pattern.compile("^spring-security-(\\d+)\\.(\\d+)\\.xsd$");
|
||||
|
||||
/**
|
||||
* If matches xsd with major minor version (e.g. spring-security-5.1.xsd returns it, otherwise null
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
static XsdFileMajorMinorVersion create(File file) {
|
||||
String fileName = file.getName();
|
||||
Matcher matcher = FILE_MAJOR_MINOR_VERSION_PATTERN.matcher(fileName);
|
||||
if (!matcher.find()) {
|
||||
return null;
|
||||
}
|
||||
int major = Integer.parseInt(matcher.group(1));
|
||||
int minor = Integer.parseInt(matcher.group(2));
|
||||
MajorMinorVersion version = new MajorMinorVersion(major, minor);
|
||||
return new XsdFileMajorMinorVersion(file, version);
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public MajorMinorVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
static class MajorMinorVersion {
|
||||
private final int major;
|
||||
|
||||
private final int minor;
|
||||
|
||||
MajorMinorVersion(int major, int minor) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public boolean isGreaterThan(MajorMinorVersion version) {
|
||||
if (getMajor() > version.getMajor()) {
|
||||
return true;
|
||||
}
|
||||
if (getMajor() < version.getMajor()) {
|
||||
return false;
|
||||
}
|
||||
if (getMinor() > version.getMinor()) {
|
||||
return true;
|
||||
}
|
||||
if (getMinor() < version.getMinor()) {
|
||||
return false;
|
||||
}
|
||||
// they are equal
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2019-2023 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
|
||||
*
|
||||
* https://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.gradle.xsd;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.MajorMinorVersion;
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask.XsdFileMajorMinorVersion;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class CreateVersionlessXsdTaskTests {
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenValid() {
|
||||
File file = new File("spring-security-2.0.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNotNull();
|
||||
assertThat(xsdFile.getFile()).isEqualTo(file);
|
||||
assertThat(xsdFile.getVersion().getMajor()).isEqualTo(2);
|
||||
assertThat(xsdFile.getVersion().getMinor()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenPatchReleaseThenNull() {
|
||||
File file = new File("spring-security-2.0.1.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenNotXsdFileThenNull() {
|
||||
File file = new File("spring-security-2.0.txt");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void xsdCreateWhenNotStartWithSpringSecurityThenNull() {
|
||||
File file = new File("spring-securityNO-2.0.xsd");
|
||||
XsdFileMajorMinorVersion xsdFile = XsdFileMajorMinorVersion.create(file);
|
||||
assertThat(xsdFile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMajorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(2,0);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMinorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(1,1);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenMajorAndMinorLarger() {
|
||||
MajorMinorVersion larger = new MajorMinorVersion(2,1);
|
||||
MajorMinorVersion smaller = new MajorMinorVersion(1,0);
|
||||
assertThat(larger.isGreaterThan(smaller)).isTrue();
|
||||
assertThat(smaller.isGreaterThan(larger)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isGreaterWhenSame() {
|
||||
MajorMinorVersion first = new MajorMinorVersion(1,0);
|
||||
MajorMinorVersion second = new MajorMinorVersion(1,0);
|
||||
assertThat(first.isGreaterThan(second)).isFalse();
|
||||
assertThat(second.isGreaterThan(first)).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
|
||||
|
||||
apply plugin: 'io.spring.convention.spring-module'
|
||||
apply plugin: 'trang'
|
||||
@@ -113,6 +114,16 @@ dependencies {
|
||||
testRuntimeOnly 'org.hsqldb:hsqldb'
|
||||
}
|
||||
|
||||
def versionlessXsd = project.tasks.create("versionlessXsd", CreateVersionlessXsdTask) {
|
||||
inputFiles.from(project.sourceSets.main.resources)
|
||||
versionlessXsdFile = project.layout.buildDirectory.file("versionlessXsd/spring-security.xsd")
|
||||
}
|
||||
|
||||
processResources {
|
||||
from(versionlessXsd) {
|
||||
into 'org/springframework/security/config/'
|
||||
}
|
||||
}
|
||||
|
||||
rncToXsd {
|
||||
rncDir = file('src/main/resources/org/springframework/security/config/')
|
||||
|
||||
+23
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.security.config.web.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -23,6 +24,8 @@ import org.springframework.security.web.server.util.matcher.OrServerWebExchangeM
|
||||
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher;
|
||||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
|
||||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
@@ -62,7 +65,8 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> {
|
||||
* {@link ServerWebExchangeMatcher}
|
||||
*/
|
||||
public T pathMatchers(HttpMethod method, String... antPatterns) {
|
||||
return matcher(ServerWebExchangeMatchers.pathMatchers(method, antPatterns));
|
||||
List<PathPattern> pathPatterns = parsePatterns(antPatterns);
|
||||
return matcher(ServerWebExchangeMatchers.pathMatchers(method, pathPatterns.toArray(new PathPattern[0])));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +78,19 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> {
|
||||
* {@link ServerWebExchangeMatcher}
|
||||
*/
|
||||
public T pathMatchers(String... antPatterns) {
|
||||
return matcher(ServerWebExchangeMatchers.pathMatchers(antPatterns));
|
||||
List<PathPattern> pathPatterns = parsePatterns(antPatterns);
|
||||
return matcher(ServerWebExchangeMatchers.pathMatchers(pathPatterns.toArray(new PathPattern[0])));
|
||||
}
|
||||
|
||||
private List<PathPattern> parsePatterns(String[] antPatterns) {
|
||||
PathPatternParser parser = getPathPatternParser();
|
||||
List<PathPattern> pathPatterns = new ArrayList<>(antPatterns.length);
|
||||
for (String pattern : antPatterns) {
|
||||
pattern = parser.initFullPathPattern(pattern);
|
||||
PathPattern pathPattern = parser.parse(pattern);
|
||||
pathPatterns.add(pathPattern);
|
||||
}
|
||||
return pathPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,6 +112,10 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> {
|
||||
*/
|
||||
protected abstract T registerMatcher(ServerWebExchangeMatcher matcher);
|
||||
|
||||
protected PathPatternParser getPathPatternParser() {
|
||||
return PathPatternParser.defaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a {@link ServerWebExchangeMatcher} instances
|
||||
* @param matcher the {@link ServerWebExchangeMatcher} instance
|
||||
|
||||
+35
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -185,9 +185,11 @@ import org.springframework.web.cors.reactive.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.reactive.CorsProcessor;
|
||||
import org.springframework.web.cors.reactive.CorsWebFilter;
|
||||
import org.springframework.web.cors.reactive.DefaultCorsProcessor;
|
||||
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
/**
|
||||
* A {@link ServerHttpSecurity} is similar to Spring Security's {@code HttpSecurity} but
|
||||
@@ -1557,6 +1559,18 @@ public class ServerHttpSecurity {
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> T getBeanOrNull(String beanName, Class<T> requiredClass) {
|
||||
if (this.context == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return this.context.getBean(beanName, requiredClass);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private <T> String[] getBeanNamesForTypeOrEmpty(Class<T> beanClass) {
|
||||
if (this.context == null) {
|
||||
return new String[0];
|
||||
@@ -1577,6 +1591,8 @@ public class ServerHttpSecurity {
|
||||
*/
|
||||
public class AuthorizeExchangeSpec extends AbstractServerWebExchangeMatcherRegistry<AuthorizeExchangeSpec.Access> {
|
||||
|
||||
private static final String REQUEST_MAPPING_HANDLER_MAPPING_BEAN_NAME = "requestMappingHandlerMapping";
|
||||
|
||||
private DelegatingReactiveAuthorizationManager.Builder managerBldr = DelegatingReactiveAuthorizationManager
|
||||
.builder();
|
||||
|
||||
@@ -1584,6 +1600,8 @@ public class ServerHttpSecurity {
|
||||
|
||||
private boolean anyExchangeRegistered;
|
||||
|
||||
private PathPatternParser pathPatternParser;
|
||||
|
||||
/**
|
||||
* Allows method chaining to continue configuring the {@link ServerHttpSecurity}
|
||||
* @return the {@link ServerHttpSecurity} to continue configuring
|
||||
@@ -1603,6 +1621,22 @@ public class ServerHttpSecurity {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PathPatternParser getPathPatternParser() {
|
||||
if (this.pathPatternParser != null) {
|
||||
return this.pathPatternParser;
|
||||
}
|
||||
RequestMappingHandlerMapping requestMappingHandlerMapping = getBeanOrNull(
|
||||
REQUEST_MAPPING_HANDLER_MAPPING_BEAN_NAME, RequestMappingHandlerMapping.class);
|
||||
if (requestMappingHandlerMapping != null) {
|
||||
this.pathPatternParser = requestMappingHandlerMapping.getPathPatternParser();
|
||||
}
|
||||
if (this.pathPatternParser == null) {
|
||||
this.pathPatternParser = PathPatternParser.defaultInstance;
|
||||
}
|
||||
return this.pathPatternParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Access registerMatcher(ServerWebExchangeMatcher matcher) {
|
||||
Assert.state(!this.anyExchangeRegistered, () -> "Cannot register " + matcher
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
spring-security-5.7.xsd
|
||||
@@ -57,7 +57,7 @@ public class AuthenticatedVoter implements AccessDecisionVoter<Object> {
|
||||
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
|
||||
|
||||
private boolean isFullyAuthenticated(Authentication authentication) {
|
||||
return (!this.authenticationTrustResolver.isAnonymous(authentication)
|
||||
return authentication != null && (!this.authenticationTrustResolver.isAnonymous(authentication)
|
||||
&& !this.authenticationTrustResolver.isRememberMe(authentication));
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -59,6 +59,7 @@ public class AuthenticatedVoterTests {
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createAnonymous(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createRememberMe(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createFullyAuthenticated(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(null, null, def));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -68,6 +69,7 @@ public class AuthenticatedVoterTests {
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(createAnonymous(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(createRememberMe(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createFullyAuthenticated(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(null, null, def));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,6 +79,7 @@ public class AuthenticatedVoterTests {
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(createAnonymous(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createRememberMe(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_GRANTED).isEqualTo(voter.vote(createFullyAuthenticated(), null, def));
|
||||
assertThat(AccessDecisionVoter.ACCESS_DENIED).isEqualTo(voter.vote(null, null, def));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -8,10 +8,10 @@ javaPlatform {
|
||||
|
||||
dependencies {
|
||||
api platform("org.springframework:spring-framework-bom:$springFrameworkVersion")
|
||||
api platform("io.projectreactor:reactor-bom:2020.0.33")
|
||||
api platform("io.projectreactor:reactor-bom:2020.0.34")
|
||||
api platform("io.rsocket:rsocket-bom:1.1.4")
|
||||
api platform("org.junit:junit-bom:5.8.2")
|
||||
api platform("org.springframework.data:spring-data-bom:2021.2.13")
|
||||
api platform("org.springframework.data:spring-data-bom:2021.2.14")
|
||||
api platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")
|
||||
api platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4")
|
||||
api platform("com.fasterxml.jackson:jackson-bom:2.13.5")
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
aspectjVersion=1.9.19
|
||||
springJavaformatVersion=0.0.31
|
||||
springBootVersion=2.4.2
|
||||
springFrameworkVersion=5.3.28
|
||||
springFrameworkVersion=5.3.29
|
||||
openSamlVersion=3.4.6
|
||||
version=5.7.9-SNAPSHOT
|
||||
version=5.7.12
|
||||
kotlinVersion=1.6.21
|
||||
samplesBranch=5.7.x
|
||||
org.gradle.jvmargs=-Xmx3g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -42,8 +42,6 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PathPatternParserServerWebExchangeMatcher.class);
|
||||
|
||||
private static final PathPatternParser DEFAULT_PATTERN_PARSER = new PathPatternParser();
|
||||
|
||||
private final PathPattern pattern;
|
||||
|
||||
private final HttpMethod method;
|
||||
@@ -60,7 +58,7 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe
|
||||
|
||||
public PathPatternParserServerWebExchangeMatcher(String pattern, HttpMethod method) {
|
||||
Assert.notNull(pattern, "pattern cannot be null");
|
||||
this.pattern = DEFAULT_PATTERN_PARSER.parse(pattern);
|
||||
this.pattern = parse(pattern);
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@@ -68,6 +66,12 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe
|
||||
this(pattern, null);
|
||||
}
|
||||
|
||||
private PathPattern parse(String pattern) {
|
||||
PathPatternParser parser = PathPatternParser.defaultInstance;
|
||||
pattern = parser.initFullPathPattern(pattern);
|
||||
return parser.parse(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<MatchResult> matches(ServerWebExchange exchange) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
+26
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -23,6 +23,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
/**
|
||||
* Provides factory methods for creating common {@link ServerWebExchangeMatcher}
|
||||
@@ -59,6 +60,30 @@ public abstract class ServerWebExchangeMatchers {
|
||||
return pathMatchers(null, patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that matches on any of the provided {@link PathPattern}s.
|
||||
* @param pathPatterns the {@link PathPattern}s to match on
|
||||
* @return the matcher to use
|
||||
*/
|
||||
public static ServerWebExchangeMatcher pathMatchers(PathPattern... pathPatterns) {
|
||||
return pathMatchers(null, pathPatterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that matches on the specific method and any of the provided
|
||||
* {@link PathPattern}s.
|
||||
* @param method the method to match on. If null, any method will be matched.
|
||||
* @param pathPatterns the {@link PathPattern}s to match on
|
||||
* @return the matcher to use
|
||||
*/
|
||||
public static ServerWebExchangeMatcher pathMatchers(HttpMethod method, PathPattern... pathPatterns) {
|
||||
List<ServerWebExchangeMatcher> matchers = new ArrayList<>(pathPatterns.length);
|
||||
for (PathPattern pathPattern : pathPatterns) {
|
||||
matchers.add(new PathPatternParserServerWebExchangeMatcher(pathPattern, method));
|
||||
}
|
||||
return new OrServerWebExchangeMatcher(matchers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher that will match on any of the provided matchers
|
||||
* @param matchers the matchers to match on
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2023 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
|
||||
*
|
||||
* https://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.web.server.util.matcher;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PathPatternParserServerWebExchangeMatcher}
|
||||
*
|
||||
* @author Marcus da Coregio
|
||||
*/
|
||||
class PathPatternParserServerWebExchangeMatcherTests {
|
||||
|
||||
@Test
|
||||
void matchesWhenConfiguredWithNoTrailingSlashAndPathContainsSlashThenMatches() {
|
||||
PathPatternParserServerWebExchangeMatcher matcher = new PathPatternParserServerWebExchangeMatcher("user/**");
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/user/test").build();
|
||||
assertThat(matcher.matches(MockServerWebExchange.from(request)).block().isMatch()).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user