Skip to content

Commit 7c98416

Browse files
2 parents e31564f + 4ffec6d commit 7c98416

File tree

421 files changed

+2386
-989
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

421 files changed

+2386
-989
lines changed

.github/workflows/check-snapshots.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: CI
2+
3+
on:
4+
schedule:
5+
- cron: '0 10 * * *' # Once per day at 10am UTC
6+
workflow_dispatch: # Manual trigger
7+
8+
env:
9+
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
snapshot-test:
16+
name: Test Against Snapshots
17+
uses: spring-io/spring-security-release-tools/.github/workflows/test.yml@v1
18+
strategy:
19+
matrix:
20+
include:
21+
- java-version: 21-ea
22+
toolchain: 21
23+
- java-version: 17
24+
toolchain: 17
25+
with:
26+
java-version: ${{ matrix.java-version }}
27+
test-args: --refresh-dependencies -PforceMavenRepositories=snapshot,https://oss.sonatype.org/content/repositories/snapshots -PisOverrideVersionCatalog -PtestToolchain=${{ matrix.toolchain }} -PspringFrameworkVersion=7.+ -PreactorVersion=2025.+ -PspringDataVersion=2025.+ --stacktrace
28+
secrets: inherit
29+
send-notification:
30+
name: Send Notification
31+
needs: [ snapshot-test ]
32+
if: ${{ !success() }}
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Send Notification
36+
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@v1
37+
with:
38+
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}

.github/workflows/continuous-integration-workflow.yml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,24 @@ jobs:
2727
java-version: ${{ matrix.jdk }}
2828
distribution: temurin
2929
secrets: inherit
30-
test:
31-
name: Test Against Snapshots
32-
uses: spring-io/spring-security-release-tools/.github/workflows/test.yml@v1
33-
strategy:
34-
matrix:
35-
include:
36-
- java-version: 21-ea
37-
toolchain: 21
38-
- java-version: 17
39-
toolchain: 17
40-
with:
41-
java-version: ${{ matrix.java-version }}
42-
test-args: --refresh-dependencies -PforceMavenRepositories=snapshot,https://oss.sonatype.org/content/repositories/snapshots -PisOverrideVersionCatalog -PtestToolchain=${{ matrix.toolchain }} -PspringFrameworkVersion=7.+ -PreactorVersion=2025.+ -PspringDataVersion=2025.+ --stacktrace
43-
secrets: inherit
4430
deploy-artifacts:
4531
name: Deploy Artifacts
46-
needs: [ build, test]
32+
needs: [ build]
4733
uses: spring-io/spring-security-release-tools/.github/workflows/deploy-artifacts.yml@v1
4834
with:
4935
should-deploy-artifacts: ${{ needs.build.outputs.should-deploy-artifacts }}
36+
default-publish-milestones-central: true
5037
secrets: inherit
5138
deploy-docs:
5239
name: Deploy Docs
53-
needs: [ build, test ]
40+
needs: [ build ]
5441
uses: spring-io/spring-security-release-tools/.github/workflows/deploy-docs.yml@v1
5542
with:
5643
should-deploy-docs: ${{ needs.build.outputs.should-deploy-artifacts }}
5744
secrets: inherit
5845
deploy-schema:
5946
name: Deploy Schema
60-
needs: [ build, test ]
47+
needs: [ build ]
6148
uses: spring-io/spring-security-release-tools/.github/workflows/deploy-schema.yml@v1
6249
with:
6350
should-deploy-schema: ${{ needs.build.outputs.should-deploy-artifacts }}
@@ -69,7 +56,7 @@ jobs:
6956
with:
7057
should-perform-release: ${{ needs.deploy-artifacts.outputs.artifacts-deployed }}
7158
project-version: ${{ needs.deploy-artifacts.outputs.project-version }}
72-
milestone-repo-url: https://repo.spring.io/artifactory/milestone
59+
milestone-repo-url: https://repo1.maven.org/maven2
7360
release-repo-url: https://repo1.maven.org/maven2
7461
artifact-path: org/springframework/security/spring-security-core
7562
slack-announcing-id: spring-security-announcing

buildSrc/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ configurations {
6464
dependencies {
6565
implementation platform(libs.io.projectreactor.reactor.bom)
6666

67+
implementation libs.spring.nullability
6768
implementation libs.com.google.code.gson.gson
6869
implementation libs.com.thaiopensource.trag
6970
implementation libs.net.sourceforge.saxon.saxon
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plugins {
2+
id 'io.spring.nullability'
3+
}

config/spring-security-config.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
optional project(':spring-security-oauth2-resource-server')
3232
optional project(':spring-security-rsocket')
3333
optional project(':spring-security-web')
34+
optional project(':spring-security-webauthn')
3435
optional 'io.projectreactor:reactor-core'
3536
optional 'org.aspectj:aspectjweaver'
3637
optional 'org.springframework:spring-jdbc'
@@ -43,7 +44,6 @@ dependencies {
4344
optional 'org.jetbrains.kotlin:kotlin-reflect'
4445
optional 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
4546
optional 'jakarta.annotation:jakarta.annotation-api'
46-
optional libs.webauthn4j.core
4747

4848
provided 'jakarta.servlet:jakarta.servlet-api'
4949

@@ -57,6 +57,7 @@ dependencies {
5757
testImplementation project(':spring-security-saml2-service-provider')
5858
testImplementation project(path : ':spring-security-saml2-service-provider', configuration : 'tests')
5959
testImplementation project(path : ':spring-security-web', configuration : 'tests')
60+
testImplementation project(path : ':spring-security-webauthn', configuration : 'tests')
6061
testImplementation "jakarta.inject:jakarta.inject-api"
6162
testImplementation "org.assertj:assertj-core"
6263
testImplementation "org.junit.jupiter:junit-jupiter-api"

config/src/main/java/org/springframework/security/config/annotation/AbstractConfiguredSecurityBuilder.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
* @param <O> The object that this builder returns
5151
* @param <B> The type of this builder (that is returned by the base class)
5252
* @author Rob Winch
53+
* @author DingHao
5354
* @see WebSecurity
5455
*/
5556
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
@@ -59,7 +60,7 @@ public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBui
5960

6061
private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<>();
6162

62-
private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<>();
63+
private List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<>();
6364

6465
private final Map<Class<?>, Object> sharedObjects = new HashMap<>();
6566

@@ -369,8 +370,12 @@ private void init() throws Exception {
369370
for (SecurityConfigurer<O, B> configurer : configurers) {
370371
configurer.init((B) this);
371372
}
372-
for (SecurityConfigurer<O, B> configurer : this.configurersAddedInInitializing) {
373-
configurer.init((B) this);
373+
while (!this.configurersAddedInInitializing.isEmpty()) {
374+
List<SecurityConfigurer<O, B>> toInit = this.configurersAddedInInitializing;
375+
this.configurersAddedInInitializing = new ArrayList<>();
376+
for (SecurityConfigurer<O, B> configurer : toInit) {
377+
configurer.init((B) this);
378+
}
374379
}
375380
}
376381

config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyDataConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ DataTargetVisitor dataTargetVisitor() {
4949
return new DataTargetVisitor();
5050
}
5151

52-
private static final class DataTargetVisitor implements AuthorizationAdvisorProxyFactory.TargetVisitor, Ordered {
52+
static final class DataTargetVisitor implements AuthorizationAdvisorProxyFactory.TargetVisitor, Ordered {
5353

5454
private static final int DEFAULT_ORDER = 200;
5555

config/src/main/java/org/springframework/security/config/annotation/method/configuration/ReactiveMethodSecuritySelector.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ class ReactiveMethodSecuritySelector implements ImportSelector {
3838
private static final boolean isDataPresent = ClassUtils
3939
.isPresent("org.springframework.security.data.aot.hint.AuthorizeReturnObjectDataHintsRegistrar", null);
4040

41-
private static final boolean isWebPresent = ClassUtils.isPresent("org.springframework.web.server.ServerWebExchange",
42-
null);
43-
4441
private static final boolean isObservabilityPresent = ClassUtils
4542
.isPresent("io.micrometer.observation.ObservationRegistry", null);
4643

@@ -64,9 +61,6 @@ public String[] selectImports(AnnotationMetadata importMetadata) {
6461
if (isDataPresent) {
6562
imports.add(AuthorizationProxyDataConfiguration.class.getName());
6663
}
67-
if (isWebPresent) {
68-
imports.add(AuthorizationProxyWebConfiguration.class.getName());
69-
}
7064
if (isObservabilityPresent) {
7165
imports.add(ReactiveMethodObservationConfiguration.class.getName());
7266
}

config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
180180

181181
private OAuth2AuthorizedClientRepository authorizedClientRepository;
182182

183+
private SecurityContextRepository securityContextRepository;
184+
183185
/**
184186
* Sets the repository of client registrations.
185187
* @param clientRegistrationRepository the repository of client registrations
@@ -233,6 +235,17 @@ public OAuth2LoginConfigurer<B> loginProcessingUrl(String loginProcessingUrl) {
233235
return this;
234236
}
235237

238+
/**
239+
* Sets the {@link SecurityContextRepository} to use.
240+
* @param securityContextRepository the {@link SecurityContextRepository} to use
241+
* @return the {@link OAuth2LoginConfigurer} for further configuration
242+
*/
243+
@Override
244+
public OAuth2LoginConfigurer<B> securityContextRepository(SecurityContextRepository securityContextRepository) {
245+
this.securityContextRepository = securityContextRepository;
246+
return this;
247+
}
248+
236249
/**
237250
* Sets the registry for managing the OIDC client-provider session link
238251
* @param oidcSessionRegistry the {@link OidcSessionRegistry} to use
@@ -299,6 +312,9 @@ public void init(B http) throws Exception {
299312
RequestMatcher processUri = getRequestMatcherBuilder().matcher(this.loginProcessingUrl);
300313
authenticationFilter.setRequiresAuthenticationRequestMatcher(processUri);
301314
authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
315+
if (this.securityContextRepository != null) {
316+
authenticationFilter.setSecurityContextRepository(this.securityContextRepository);
317+
}
302318
this.setAuthenticationFilter(authenticationFilter);
303319
super.loginProcessingUrl(this.loginProcessingUrl);
304320
if (this.loginPage != null) {

config/src/main/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBean.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public final class PathPatternRequestMatcherBuilderFactoryBean implements
4646

4747
private final PathPatternParser parser;
4848

49+
private String basePath;
50+
4951
private ApplicationContext context;
5052

5153
private String beanName;
@@ -78,23 +80,43 @@ public PathPatternRequestMatcherBuilderFactoryBean(PathPatternParser parser) {
7880
public PathPatternRequestMatcher.Builder getObject() throws Exception {
7981
if (!this.context.containsBean(MVC_PATTERN_PARSER_BEAN_NAME)) {
8082
PathPatternParser parser = (this.parser != null) ? this.parser : PathPatternParser.defaultInstance;
81-
return PathPatternRequestMatcher.withPathPatternParser(parser);
83+
return withPathPatternParser(parser);
8284
}
8385
PathPatternParser mvc = this.context.getBean(MVC_PATTERN_PARSER_BEAN_NAME, PathPatternParser.class);
8486
PathPatternParser parser = (this.parser != null) ? this.parser : mvc;
8587
if (mvc.equals(parser)) {
86-
return PathPatternRequestMatcher.withPathPatternParser(parser);
88+
return withPathPatternParser(parser);
8789
}
8890
throw new IllegalArgumentException("Spring Security and Spring MVC must use the same path pattern parser. "
8991
+ "To have Spring Security use Spring MVC's [" + describe(mvc, MVC_PATTERN_PARSER_BEAN_NAME)
9092
+ "] simply publish this bean [" + describe(this, this.beanName) + "] using its default constructor");
9193
}
9294

95+
private PathPatternRequestMatcher.Builder withPathPatternParser(PathPatternParser parser) {
96+
if (this.basePath == null) {
97+
return PathPatternRequestMatcher.withPathPatternParser(parser);
98+
}
99+
else {
100+
return PathPatternRequestMatcher.withPathPatternParser(parser).basePath(this.basePath);
101+
}
102+
}
103+
93104
@Override
94105
public Class<?> getObjectType() {
95106
return PathPatternRequestMatcher.Builder.class;
96107
}
97108

109+
/**
110+
* Use this as the base path for patterns built by the resulting
111+
* {@link PathPatternRequestMatcher.Builder} instance
112+
* @param basePath the base path to use
113+
* @since 7.0
114+
* @see PathPatternRequestMatcher.Builder#basePath(String)
115+
*/
116+
public void setBasePath(String basePath) {
117+
this.basePath = basePath;
118+
}
119+
98120
@Override
99121
public void setApplicationContext(ApplicationContext context) throws BeansException {
100122
this.context = context;

0 commit comments

Comments
 (0)