Compare commits
124 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cab91b485 | |||
| 82241b6cb8 | |||
| 7cecfbb4db | |||
| 5b923c78ea | |||
| 6eb16dc35e | |||
| bd4f9a1644 | |||
| 65a1099ccb | |||
| 1ad93f45f8 | |||
| 8c9a8e3f6c | |||
| a8f54db7e4 | |||
| 24bfdc1dee | |||
| 8876c30b00 | |||
| 94d36e603b | |||
| ade851b2f1 | |||
| 9fdd2dc675 | |||
| 86fe79a848 | |||
| 329e9e6d71 | |||
| 09a3280442 | |||
| 852e81640b | |||
| 2aa3c1ab2e | |||
| 17c58ef088 | |||
| 88aedba0bf | |||
| f95a956345 | |||
| fd233120a8 | |||
| 30cc0f21a9 | |||
| c096e45242 | |||
| b3e262187c | |||
| 64fa98da1a | |||
| 63306ad8ee | |||
| 24aec1d002 | |||
| 863753580c | |||
| fa92ce3758 | |||
| 26b20b2dd2 | |||
| e7a4349774 | |||
| 22f4a5d4da | |||
| 561f1bba0f | |||
| e4d43fb89a | |||
| 268fce2616 | |||
| c4c547b73b | |||
| d487048224 | |||
| 1d15210ae2 | |||
| 5f377e5ec2 | |||
| e107329766 | |||
| 04c08bb42a | |||
| c96eca3ef4 | |||
| 905b4786e8 | |||
| 08d3108521 | |||
| 73c93cebaf | |||
| 3c6df7df1f | |||
| 70b161c772 | |||
| e3139ff669 | |||
| 36e7420bd0 | |||
| f03e612a14 | |||
| ebd3f2364c | |||
| 7fd2a726d6 | |||
| dfacecdb88 | |||
| 92b8883fc2 | |||
| 43731e0523 | |||
| f686a9e313 | |||
| 08d062bdc0 | |||
| 2c4db99229 | |||
| c84875f923 | |||
| 8d452e2c32 | |||
| 0f6f453ea0 | |||
| 7ec316a030 | |||
| 61fae604d2 | |||
| 1eef373ca0 | |||
| 7a03cd5a55 | |||
| bb59d5c0dd | |||
| e4fafce066 | |||
| 2104c49597 | |||
| 5bee669ae3 | |||
| c5b1f78118 | |||
| f94cef17b8 | |||
| 25f2e1c2a3 | |||
| 67a3de25eb | |||
| 5bd6b4a570 | |||
| 08dcb1c0e4 | |||
| e1ad5d2392 | |||
| 7654aa2f6f | |||
| a29d4ad5a4 | |||
| ab33b40f19 | |||
| d3d6497798 | |||
| 6680d42d34 | |||
| c2efa64c4d | |||
| 0a75d5b785 | |||
| d2366650ec | |||
| 39790c0a7e | |||
| 5338b7a05b | |||
| 71f81dede2 | |||
| bd86d0b233 | |||
| f8442794a8 | |||
| b62affe126 | |||
| 60e7733d8a | |||
| 2bac0be1d6 | |||
| bb51ad6096 | |||
| 9161eced5b | |||
| 769fd66ed3 | |||
| 49ecfa71dd | |||
| c6d41fd1a5 | |||
| 316cf90ec2 | |||
| f5fbc2b46b | |||
| 49d2ebf3cf | |||
| fc2c927a72 | |||
| 40de3ed6bb | |||
| 85e8221ba0 | |||
| 7f753a2433 | |||
| ed7ae7969e | |||
| 4ddef4ed83 | |||
| abb8aa54d8 | |||
| deb298ee81 | |||
| 3565d9bd9d | |||
| 827a689ef8 | |||
| 43f958e058 | |||
| 5594fc018f | |||
| bf06d19225 | |||
| d511a4badb | |||
| 038a6601d8 | |||
| 57c2af4900 | |||
| 4690f1bb8a | |||
| 6da4ea0d0d | |||
| 8f69721f24 | |||
| acd131c3d1 | |||
| 73b077790f |
+51
-46
@@ -4,52 +4,6 @@ registries:
|
||||
type: maven-repository
|
||||
url: https://build.shibboleth.net/maven/releases
|
||||
updates:
|
||||
# 6.5.x
|
||||
- package-ecosystem: gradle
|
||||
target-branch: 6.5.x
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '03:00'
|
||||
timezone: Etc/UTC
|
||||
labels:
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
registries:
|
||||
- shibboleth
|
||||
ignore:
|
||||
- dependency-name: com.nimbusds:nimbus-jose-jwt
|
||||
- dependency-name: org.python:jython
|
||||
- dependency-name: org.apache.directory.server:*
|
||||
- dependency-name: org.apache.directory.shared:*
|
||||
- dependency-name: org.junit:junit-bom
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- dependency-name: org.mockito:mockito-bom
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- dependency-name: '*'
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- version-update:semver-minor
|
||||
- package-ecosystem: npm
|
||||
target-branch: 6.5.x
|
||||
directory: /docs
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- 'type: task'
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
- package-ecosystem: github-actions
|
||||
target-branch: 6.5.x
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- 'type: task'
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
|
||||
# 7.0.x
|
||||
- package-ecosystem: gradle
|
||||
@@ -103,6 +57,57 @@ updates:
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
|
||||
# 7.1.x
|
||||
- package-ecosystem: gradle
|
||||
target-branch: 7.1.x
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '03:00'
|
||||
timezone: Etc/UTC
|
||||
labels:
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
registries:
|
||||
- shibboleth
|
||||
ignore:
|
||||
- dependency-name: com.nimbusds:nimbus-jose-jwt
|
||||
- dependency-name: org.python:jython
|
||||
- dependency-name: org.apache.directory.server:*
|
||||
- dependency-name: org.apache.directory.shared:*
|
||||
- dependency-name: org.junit:junit-bom
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- dependency-name: org.mockito:mockito-bom
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- dependency-name: com.gradle.enterprise
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- version-update:semver-minor
|
||||
- dependency-name: '*'
|
||||
update-types:
|
||||
- version-update:semver-major
|
||||
- version-update:semver-minor
|
||||
- package-ecosystem: npm
|
||||
target-branch: 7.1.x
|
||||
directory: /docs
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- 'type: task'
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
- package-ecosystem: github-actions
|
||||
target-branch: 7.1.x
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- 'type: task'
|
||||
- 'type: dependency-upgrade'
|
||||
- 'in: build'
|
||||
|
||||
# main
|
||||
- package-ecosystem: gradle
|
||||
target-branch: main
|
||||
|
||||
@@ -44,22 +44,9 @@ jobs:
|
||||
should-deploy-schema: ${{ needs.build.outputs.should-deploy-artifacts }}
|
||||
java-version: 25
|
||||
secrets: inherit
|
||||
perform-release:
|
||||
name: Perform Release
|
||||
needs: [ deploy-artifacts, deploy-schema ]
|
||||
uses: spring-io/spring-security-release-tools/.github/workflows/perform-release.yml@b92832ecbc7cbe969201e6beafbde0ee400cf095 # v1.0.15
|
||||
with:
|
||||
should-perform-release: ${{ needs.deploy-artifacts.outputs.artifacts-deployed }}
|
||||
project-version: ${{ needs.deploy-artifacts.outputs.project-version }}
|
||||
milestone-repo-url: https://repo1.maven.org/maven2
|
||||
release-repo-url: https://repo1.maven.org/maven2
|
||||
artifact-path: org/springframework/security/spring-security-core
|
||||
slack-announcing-id: spring-security-announcing
|
||||
java-version: 25
|
||||
secrets: inherit
|
||||
send-notification:
|
||||
name: Send Notification
|
||||
needs: [ perform-release ]
|
||||
needs: [ deploy-artifacts, deploy-schema ]
|
||||
if: ${{ !success() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Compute Version
|
||||
id: compute-version
|
||||
uses: spring-io/spring-release-actions/compute-version@a1f321783a0769dd2aea4fad6c2ae2f95a52b885 # 0.0.5
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: github.repository_owner == 'spring-projects'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: docs-build
|
||||
fetch-depth: 1
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
name: Finalize Release
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
inputs:
|
||||
version:
|
||||
description: The Spring Security release to finalize (e.g. 7.0.0-RC2)
|
||||
required: true
|
||||
|
||||
env:
|
||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
perform-release:
|
||||
name: Perform Release
|
||||
uses: spring-io/spring-security-release-tools/.github/workflows/perform-release.yml@b92832ecbc7cbe969201e6beafbde0ee400cf095 # v1.0.15
|
||||
with:
|
||||
should-perform-release: true
|
||||
project-version: ${{ inputs.version }}
|
||||
milestone-repo-url: https://repo1.maven.org/maven2
|
||||
release-repo-url: https://repo1.maven.org/maven2
|
||||
artifact-path: org/springframework/security/spring-security-core
|
||||
slack-announcing-id: spring-security-announcing
|
||||
secrets: inherit
|
||||
@@ -20,9 +20,9 @@ jobs:
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Set up JDK 25
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: 'temurin'
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
name: Check Milestone
|
||||
on:
|
||||
milestone:
|
||||
types: [created, opened, edited]
|
||||
env:
|
||||
DUE_ON: ${{ github.event.milestone.due_on }}
|
||||
TITLE: ${{ github.event.milestone.title }}
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
spring-releasetrain-checks:
|
||||
name: Check DueOn is on a Release Date
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'spring-projects/spring-security' }}
|
||||
permissions:
|
||||
contents: none
|
||||
steps:
|
||||
- name: Print Milestone Being Checked
|
||||
run: echo "Validating DueOn '$DUE_ON' for milestone '$TITLE'"
|
||||
- name: Validate DueOn
|
||||
if: env.DUE_ON != ''
|
||||
run: |
|
||||
export TOOL_VERSION=0.1.1
|
||||
wget "https://repo.maven.apache.org/maven2/io/spring/releasetrain/spring-release-train-tools/$TOOL_VERSION/spring-release-train-tools-$TOOL_VERSION.jar"
|
||||
java -cp "spring-release-train-tools-$TOOL_VERSION.jar" io.spring.releasetrain.CheckMilestoneDueOnMain --dueOn "$DUE_ON" --expectedDayOfWeek MONDAY --expectedMondayCount 3
|
||||
send-notification:
|
||||
name: Send Notification
|
||||
needs: [ spring-releasetrain-checks ]
|
||||
if: ${{ failure() || cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send Notification
|
||||
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@b92832ecbc7cbe969201e6beafbde0ee400cf095 # v1.0.15
|
||||
with:
|
||||
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'spring-projects/spring-security' }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@c8668747d7c264864c8c7f7026d0d277d14a78dc # v2.0.6
|
||||
with:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'spring-projects/spring-security' }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Set up gradle
|
||||
uses: spring-io/spring-gradle-build-action@c8668747d7c264864c8c7f7026d0d277d14a78dc # v2.0.6
|
||||
with:
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
name: Release Scheduler
|
||||
on:
|
||||
schedule:
|
||||
- cron: '15 15 * * MON' # Every Monday at 3:15pm UTC
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
jobs:
|
||||
dispatch_scheduled_releases:
|
||||
name: Dispatch scheduled releases
|
||||
if: github.repository_owner == 'spring-projects'
|
||||
strategy:
|
||||
matrix:
|
||||
# List of active maintenance branches.
|
||||
branch: [ main, 7.0.x, 6.5.x, 6.4.x, 6.3.x ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Dispatch
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
run: gh workflow run update-scheduled-release-version.yml -r ${{ matrix.branch }}
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
branch: [ '6.5.x', '7.0.x', 'main' ]
|
||||
branch: [ '6.5.x', '7.0.x', '7.1.x', 'main' ]
|
||||
steps:
|
||||
- uses: spring-io/spring-doc-actions/update-antora-spring-ui@415e2b11a766ba64799fffb5c97a4f7e17f677cf # v0.0.22
|
||||
name: Update
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
name: Update Scheduled Release Version
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger only. Triggered by release-scheduler.yml on main.
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update-scheduled-release-version:
|
||||
name: Update Scheduled Release Version
|
||||
uses: spring-io/spring-security-release-tools/.github/workflows/update-scheduled-release-version.yml@b92832ecbc7cbe969201e6beafbde0ee400cf095 # v1.0.15
|
||||
secrets: inherit
|
||||
send-notification:
|
||||
name: Send Notification
|
||||
needs: [ update-scheduled-release-version ]
|
||||
if: ${{ failure() || cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send Notification
|
||||
uses: spring-io/spring-security-release-tools/.github/actions/send-notification@b92832ecbc7cbe969201e6beafbde0ee400cf095 # v1.0.15
|
||||
with:
|
||||
webhook-url: ${{ secrets.SPRING_SECURITY_CI_GCHAT_WEBHOOK_URL }}
|
||||
@@ -14,6 +14,16 @@ repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven { url = 'https://repo.spring.io/snapshot' }
|
||||
if (System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_URL") != null) {
|
||||
maven {
|
||||
name = "Release Train"
|
||||
url = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_URL")
|
||||
credentials {
|
||||
username = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME")
|
||||
password = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
+10
@@ -43,6 +43,16 @@ class RepositoryConventionPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
if (System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_URL") != null) {
|
||||
maven {
|
||||
name = "Release Train"
|
||||
url = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_URL")
|
||||
credentials {
|
||||
username = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME")
|
||||
password = System.getenv("RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isSnapshot) {
|
||||
maven {
|
||||
name = 'artifactory-snapshot'
|
||||
|
||||
+6
@@ -22,6 +22,12 @@ public class MavenPublishingConventionsPlugin implements Plugin<Project> {
|
||||
@Override
|
||||
public void execute(MavenPublishPlugin mavenPublish) {
|
||||
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
|
||||
if (project.hasProperty("deploymentRepository")) {
|
||||
publishing.getRepositories().maven((mavenRepository) -> {
|
||||
mavenRepository.setUrl(project.property("deploymentRepository"));
|
||||
mavenRepository.setName("deployment");
|
||||
});
|
||||
}
|
||||
publishing.getPublications().withType(MavenPublication.class)
|
||||
.all((mavenPublication) -> MavenPublishingConventionsPlugin.this.customizePom(mavenPublication.getPom(), project));
|
||||
MavenPublishingConventionsPlugin.this.customizeJavaPlugin(project);
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
|
||||
protected CasAuthenticationToken(Builder<?> builder) {
|
||||
super(builder);
|
||||
Assert.isTrue(!"".equals(builder.principal), "principal cannot be null or empty");
|
||||
Assert.notNull(!"".equals(builder.credentials), "credentials cannot be null or empty");
|
||||
Assert.isTrue(!"".equals(builder.credentials), "credentials cannot be null or empty");
|
||||
Assert.notNull(builder.userDetails, "userDetails cannot be null");
|
||||
Assert.notNull(builder.assertion, "assertion cannot be null");
|
||||
this.keyHash = builder.keyHash;
|
||||
|
||||
+35
@@ -34,6 +34,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
|
||||
/**
|
||||
* Tests {@link CasAuthenticationToken}.
|
||||
@@ -182,4 +183,38 @@ public class CasAuthenticationTokenTests {
|
||||
assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenPrincipalIsEmpty() {
|
||||
final Assertion assertion = new AssertionImpl("test");
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", this.ROLES,
|
||||
makeUserDetails(), assertion);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> token.toBuilder().principal(null).build());
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> token.toBuilder().principal("").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenPrincipalIsNotEmpty() {
|
||||
final Assertion assertion = new AssertionImpl("test");
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", this.ROLES,
|
||||
makeUserDetails(), assertion);
|
||||
assertThatNoException().isThrownBy(() -> token.toBuilder().principal("principal").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenCredentialsIsEmpty() {
|
||||
final Assertion assertion = new AssertionImpl("test");
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", this.ROLES,
|
||||
makeUserDetails(), assertion);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> token.toBuilder().credentials(null).build());
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> token.toBuilder().credentials("").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBuilderWhenCredentialsIsNotEmpty() {
|
||||
final Assertion assertion = new AssertionImpl("test");
|
||||
CasAuthenticationToken token = new CasAuthenticationToken("key", makeUserDetails(), "Password", this.ROLES,
|
||||
makeUserDetails(), assertion);
|
||||
assertThatNoException().isThrownBy(() -> token.toBuilder().credentials("credentials").build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -94,7 +94,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
public BeanDefinition parse(Element element, ParserContext pc) {
|
||||
if (!namespaceMatchesVersion(element)) {
|
||||
pc.getReaderContext()
|
||||
.fatal("You cannot use any XSD older than spring-security-7.1.xsd. Either change to spring-security.xsd or spring-security-7.1.xsd",
|
||||
.fatal("You cannot use any XSD older than spring-security-7.2.xsd. Either change to spring-security.xsd or spring-security-7.2.xsd",
|
||||
element);
|
||||
}
|
||||
String name = pc.getDelegate().getLocalName(element);
|
||||
@@ -219,7 +219,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler {
|
||||
|
||||
private boolean matchesVersionInternal(Element element) {
|
||||
String schemaLocation = element.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
|
||||
return schemaLocation.matches("(?m).*spring-security-7\\.1.*.xsd.*")
|
||||
return schemaLocation.matches("(?m).*spring-security-7\\.2.*.xsd.*")
|
||||
|| schemaLocation.matches("(?m).*spring-security.xsd.*")
|
||||
|| !schemaLocation.matches("(?m).*spring-security.*");
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
* Copyright 2004-present 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.
|
||||
|
||||
+13
@@ -39,6 +39,9 @@ import org.springframework.util.ClassUtils;
|
||||
@Deprecated
|
||||
final class GlobalMethodSecuritySelector implements ImportSelector {
|
||||
|
||||
private static final boolean isAccessPresent = ClassUtils.isPresent(
|
||||
"org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor", null);
|
||||
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
Class<EnableGlobalMethodSecurity> annoType = EnableGlobalMethodSecurity.class;
|
||||
@@ -59,16 +62,26 @@ final class GlobalMethodSecuritySelector implements ImportSelector {
|
||||
boolean jsr250Enabled = attributes.getBoolean("jsr250Enabled");
|
||||
List<String> classNames = new ArrayList<>(4);
|
||||
if (isProxy) {
|
||||
assertAccessModulePresent();
|
||||
classNames.add(MethodSecurityMetadataSourceAdvisorRegistrar.class.getName());
|
||||
}
|
||||
classNames.add(autoProxyClassName);
|
||||
if (!skipMethodSecurityConfiguration) {
|
||||
assertAccessModulePresent();
|
||||
classNames.add(GlobalMethodSecurityConfiguration.class.getName());
|
||||
}
|
||||
if (jsr250Enabled) {
|
||||
assertAccessModulePresent();
|
||||
classNames.add(Jsr250MetadataSourceConfiguration.class.getName());
|
||||
}
|
||||
return classNames.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private static void assertAccessModulePresent() {
|
||||
Assert.state(isAccessPresent,
|
||||
() -> "@EnableGlobalMethodSecurity requires the spring-security-access dependency on the "
|
||||
+ "classpath. Please add spring-security-access, or migrate to @EnableMethodSecurity "
|
||||
+ "which does not require it.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
@@ -26,6 +26,7 @@ import org.springframework.context.annotation.AutoProxyRegistrar;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -35,6 +36,8 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
class ReactiveMethodSecuritySelector implements ImportSelector {
|
||||
|
||||
private static final String METHOD_SECURITY_METADATA_SOURCE_ADVISOR = "org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor";
|
||||
|
||||
private static final boolean isDataPresent = ClassUtils
|
||||
.isPresent("org.springframework.security.data.aot.hint.AuthorizeReturnObjectDataHintsRegistrar", null);
|
||||
|
||||
@@ -56,6 +59,11 @@ class ReactiveMethodSecuritySelector implements ImportSelector {
|
||||
imports.add(ReactiveAuthorizationManagerMethodSecurityConfiguration.class.getName());
|
||||
}
|
||||
else {
|
||||
Assert.state(
|
||||
ClassUtils.isPresent(METHOD_SECURITY_METADATA_SOURCE_ADVISOR, ClassUtils.getDefaultClassLoader()),
|
||||
() -> "@EnableReactiveMethodSecurity(useAuthorizationManager = false) requires the "
|
||||
+ "spring-security-access dependency on the classpath. Please add spring-security-access, "
|
||||
+ "or use the default useAuthorizationManager = true which does not require it.");
|
||||
imports.add(ReactiveMethodSecurityConfiguration.class.getName());
|
||||
}
|
||||
if (isDataPresent) {
|
||||
|
||||
+2
-3
@@ -379,9 +379,8 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
|
||||
}
|
||||
if (filter instanceof AuthorizationFilter authorization) {
|
||||
AuthorizationManager<HttpServletRequest> authorizationManager = authorization.getAuthorizationManager();
|
||||
builder.add(securityFilterChain::matches,
|
||||
(authentication, context) -> (AuthorizationDecision) authorizationManager
|
||||
.authorize(authentication, context.getRequest()));
|
||||
builder.add(securityFilterChain::matches, (authentication, context) -> authorizationManager
|
||||
.authorize(authentication, context.getRequest()));
|
||||
mappings = true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ public final class OidcBackChannelLogoutHandler implements LogoutHandler {
|
||||
|
||||
private final OidcSessionRegistry sessionRegistry;
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private RestOperations restOperations = new RestTemplate();
|
||||
|
||||
private String logoutUri = "{baseUrl}/logout/connect/back-channel/{registrationId}";
|
||||
|
||||
+4
@@ -47,6 +47,10 @@ public class CorsBeanDefinitionParser {
|
||||
if (StringUtils.hasText(filterRef)) {
|
||||
return new RuntimeBeanReference(filterRef);
|
||||
}
|
||||
String configurationSourceRef = element.getAttribute(ATT_SOURCE);
|
||||
if (!StringUtils.hasText(configurationSourceRef)) {
|
||||
return new RootBeanDefinition(CorsFilterFactoryBean.class);
|
||||
}
|
||||
BeanMetadataElement configurationSource = getSource(element, parserContext);
|
||||
if (configurationSource == null) {
|
||||
throw new BeanCreationException("Could not create CorsFilter");
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2004-present 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.config.http;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.PreFlightRequestHandler;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
import org.springframework.web.filter.PreFlightRequestFilter;
|
||||
|
||||
class CorsFilterFactoryBean implements FactoryBean<Filter>, ApplicationContextAware {
|
||||
|
||||
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public Filter getObject() {
|
||||
if (this.context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
||||
CorsConfigurationSource source = this.context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
|
||||
CorsConfigurationSource.class);
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
String[] preFlightRequestHandlerNames = this.context.getBeanNamesForType(PreFlightRequestHandler.class);
|
||||
if (preFlightRequestHandlerNames.length == 1) {
|
||||
PreFlightRequestHandler handler = this.context.getBean(PreFlightRequestHandler.class);
|
||||
return new PreFlightRequestFilter(handler);
|
||||
}
|
||||
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME,
|
||||
"A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + " of type "
|
||||
+ CorsConfigurationSource.class.getName()
|
||||
+ " is required to use <cors>. Please ensure Spring Security & Spring "
|
||||
+ "MVC are configured in a shared ApplicationContext.");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return Filter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,9 +14,9 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-7.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-7.0.xsd=org/springframework/security/config/spring-security-7.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-7.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-7.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-7.2.xsd=org/springframework/security/config/spring-security-7.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-7.1.xsd=org/springframework/security/config/spring-security-7.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-7.0.xsd=org/springframework/security/config/spring-security-7.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-6.5.xsd=org/springframework/security/config/spring-security-6.5.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-6.4.xsd=org/springframework/security/config/spring-security-6.4.xsd
|
||||
@@ -44,7 +44,8 @@ http\://www.springframework.org/schema/security/spring-security-2.0.xsd=org/spri
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.1.xsd=org/springframework/security/config/spring-security-2.0.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.2.xsd=org/springframework/security/config/spring-security-2.0.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-2.0.4.xsd=org/springframework/security/config/spring-security-2.0.4.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-7.1.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-7.2.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security-7.2.xsd=org/springframework/security/config/spring-security-7.2.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security-7.1.xsd=org/springframework/security/config/spring-security-7.1.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security-7.0.xsd=org/springframework/security/config/spring-security-7.0.xsd
|
||||
https\://www.springframework.org/schema/security/spring-security-6.5.xsd=org/springframework/security/config/spring-security-6.5.xsd
|
||||
|
||||
+1361
File diff suppressed because it is too large
Load Diff
+3849
File diff suppressed because it is too large
Load Diff
+2
-4
@@ -304,8 +304,7 @@ class SpringSecurityCoreVersionSerializableTests {
|
||||
private static String getCurrentVersion() {
|
||||
String version = System.getProperty("springSecurityVersion");
|
||||
String[] parts = version.split("\\.");
|
||||
parts[2] = "x";
|
||||
return String.join(".", parts);
|
||||
return parts[0] + "." + parts[1] + ".x";
|
||||
}
|
||||
|
||||
private static String getPreviousVersion() {
|
||||
@@ -318,8 +317,7 @@ class SpringSecurityCoreVersionSerializableTests {
|
||||
parts[0] = String.valueOf(Integer.parseInt(parts[0]) - 1);
|
||||
parts[1] = "5"; // FIXME: this should not be hard coded
|
||||
}
|
||||
parts[2] = "x";
|
||||
return String.join(".", parts);
|
||||
return parts[0] + "." + parts[1] + ".x";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class SecurityNamespaceHandlerTests {
|
||||
"<user-service id='us'><user name='bob' password='bobspassword' authorities='ROLE_A' /></user-service>",
|
||||
"3.0.3", null))
|
||||
.withMessageContaining(
|
||||
"You cannot use any XSD older than spring-security-7.1.xsd. Either change to spring-security.xsd or spring-security-7.1.xsd");
|
||||
"You cannot use any XSD older than spring-security-7.2.xsd. Either change to spring-security.xsd or spring-security-7.2.xsd");
|
||||
}
|
||||
|
||||
// SEC-1868
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2004-present 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.config.annotation.method.configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.test.support.ClassPathExclusions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for gh-19441: {@code spring-security-access} moved
|
||||
* {@link org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor}
|
||||
* out of {@code spring-security-core} and into the optional
|
||||
* {@code spring-security-access} module. {@link EnableMethodSecurity} and
|
||||
* {@link EnableReactiveMethodSecurity}'s default (AuthorizationManager-based) mode never
|
||||
* needed that class and continue to work without {@code spring-security-access} on the
|
||||
* classpath, but the deprecated legacy method security annotations do need it and
|
||||
* previously failed with a confusing {@link NoClassDefFoundError} instead of an
|
||||
* actionable message.
|
||||
*/
|
||||
@ClassPathExclusions("spring-security-access-*.jar")
|
||||
public class Gh19441Tests {
|
||||
|
||||
@Test
|
||||
public void enableMethodSecurityWhenAccessModuleAbsentThenContextStartsCleanly() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableMethodSecurityConfig.class);
|
||||
context.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableReactiveMethodSecurityWhenAccessModuleAbsentThenContextStartsCleanly() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableReactiveMethodSecurityConfig.class);
|
||||
context.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableGlobalMethodSecurityWhenProxyModeAndAccessModuleAbsentThenClearException() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableGlobalMethodSecurityProxyConfig.class);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(context::refresh)
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessageContaining("spring-security-access");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableGlobalMethodSecurityWhenAspectJModeAndAccessModuleAbsentThenClearException() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableGlobalMethodSecurityAspectJConfig.class);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(context::refresh)
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessageContaining("spring-security-access");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableReactiveMethodSecurityWhenUseAuthorizationManagerFalseAndAccessModuleAbsentThenClearException() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableReactiveMethodSecurityLegacyConfig.class);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(context::refresh)
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessageContaining("spring-security-access");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableGlobalMethodSecurityWhenAspectJModeAndJsr250EnabledAndConfigurationSubclassedAndAccessModuleAbsentThenClearException() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(EnableGlobalMethodSecurityAspectJJsr250SubclassedConfig.class);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(context::refresh)
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessageContaining("spring-security-access");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableMethodSecurity
|
||||
static class EnableMethodSecurityConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableReactiveMethodSecurity
|
||||
static class EnableReactiveMethodSecurityConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
static class EnableGlobalMethodSecurityProxyConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ)
|
||||
static class EnableGlobalMethodSecurityAspectJConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableReactiveMethodSecurity(useAuthorizationManager = false)
|
||||
static class EnableReactiveMethodSecurityLegacyConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(jsr250Enabled = true, mode = AdviceMode.ASPECTJ)
|
||||
static class EnableGlobalMethodSecurityAspectJJsr250SubclassedConfig extends GlobalMethodSecurityConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -20,6 +20,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
@@ -75,6 +76,15 @@ public class CorsConfigurerTests {
|
||||
+ "or are publishing a `CorsConfigurationSource` bean.");
|
||||
}
|
||||
|
||||
// FIXME: Spring Framework 7.1 removed HandlerMappingIntrospector, so there is no
|
||||
// longer a CorsConfigurationSource derivable from implicit @CrossOrigin/MVC config,
|
||||
// and PreFlightRequestFilter (the replacement) is a no-op for non-preflight
|
||||
// requests. Per https://github.com/spring-projects/spring-framework/issues/36481,
|
||||
// relying on implicit config for a plain request's CORS headers was "never an
|
||||
// intended way of using HandlerMappingIntrospector" and is not coming back; decide
|
||||
// whether to update this test to require an explicit CorsConfigurationSource bean
|
||||
// (matching the reactive stack's always-explicit model), then re-enable.
|
||||
@Disabled
|
||||
@Test
|
||||
public void getWhenCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
|
||||
this.spring.register(MvcCorsConfig.class).autowire();
|
||||
@@ -95,6 +105,9 @@ public class CorsConfigurerTests {
|
||||
.andExpect(header().exists("X-Content-Type-Options"));
|
||||
}
|
||||
|
||||
// FIXME: see FIXME on getWhenCrossOriginAnnotationThenRespondsWithCorsHeaders above;
|
||||
// same root cause (Framework 7.1 removed HandlerMappingIntrospector).
|
||||
@Disabled
|
||||
@Test
|
||||
public void getWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
|
||||
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
|
||||
|
||||
+1
@@ -182,6 +182,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @author Josh Cummings
|
||||
* @author Evgeniy Cheban
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@ExtendWith(SpringTestContextExtension.class)
|
||||
public class OAuth2ResourceServerConfigurerTests {
|
||||
|
||||
|
||||
+3
-3
@@ -65,7 +65,7 @@ public class XsdDocumentedTests {
|
||||
|
||||
String schema31xDocumentLocation = "org/springframework/security/config/spring-security-3.1.xsd";
|
||||
|
||||
String schemaDocumentLocation = "org/springframework/security/config/spring-security-7.1.xsd";
|
||||
String schemaDocumentLocation = "org/springframework/security/config/spring-security-7.2.xsd";
|
||||
|
||||
XmlSupport xml = new XmlSupport();
|
||||
|
||||
@@ -151,8 +151,8 @@ public class XsdDocumentedTests {
|
||||
.list((dir, name) -> name.endsWith(".xsd"));
|
||||
// @formatter:on
|
||||
assertThat(schemas.length)
|
||||
.withFailMessage("the count is equal to 29, if not then schemaDocument needs updating")
|
||||
.isEqualTo(29);
|
||||
.withFailMessage("the count is equal to 30, if not then schemaDocument needs updating")
|
||||
.isEqualTo(30);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+34
@@ -18,6 +18,9 @@ package org.springframework.security.config.http;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
@@ -35,6 +38,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.PreFlightRequestHandler;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
@@ -67,6 +71,14 @@ public class HttpCorsConfigTests {
|
||||
"Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
|
||||
}
|
||||
|
||||
// FIXME: Spring Framework 7.1 removed HandlerMappingIntrospector, which this test's
|
||||
// implicit (no configuration-source-ref) <cors/> scenario relied on to add CORS
|
||||
// headers to a plain, non-preflight request before authorization runs. Per
|
||||
// https://github.com/spring-projects/spring-framework/issues/36481, this was "never
|
||||
// an intended way of using HandlerMappingIntrospector" and is not coming back;
|
||||
// decide whether to update this test's expectations (e.g. require an explicit
|
||||
// CorsConfigurationSource bean) or remove the assertion, then re-enable.
|
||||
@Disabled
|
||||
@Test
|
||||
public void getWhenUsingCorsThenDoesSpringSecurityCorsHandshake() throws Exception {
|
||||
this.spring.configLocations(this.xml("WithCors")).autowire();
|
||||
@@ -106,6 +118,19 @@ public class HttpCorsConfigTests {
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optionsWhenUsingPreFlightRequestHandlerThenHandlesPreFlightRequest() throws Exception {
|
||||
this.spring.configLocations(this.xml("WithPreFlightRequestHandler")).autowire();
|
||||
// @formatter:off
|
||||
this.mvc.perform(get("/").with(this.approved()))
|
||||
.andExpect(header().doesNotExist("X-Pre-Flight"))
|
||||
.andExpect(status().isIAmATeapot());
|
||||
this.mvc.perform(options("/").with(this.preflight()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().exists("X-Pre-Flight"));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
private String xml(String configName) {
|
||||
return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml";
|
||||
}
|
||||
@@ -158,4 +183,13 @@ public class HttpCorsConfigTests {
|
||||
|
||||
}
|
||||
|
||||
static class MyPreFlightRequestHandler implements PreFlightRequestHandler {
|
||||
|
||||
@Override
|
||||
public void handlePreFlight(HttpServletRequest request, HttpServletResponse response) {
|
||||
response.addHeader("X-Pre-Flight", "Handled");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -124,6 +124,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
/**
|
||||
* @author Josh Cummings
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@ExtendWith({ SpringExtension.class, SpringTestContextExtension.class })
|
||||
@SecurityTestExecutionListeners
|
||||
public class OAuth2ResourceServerBeanDefinitionParserTests {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2004-present 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.
|
||||
-->
|
||||
|
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
https://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<http entry-point-ref="ep">
|
||||
<intercept-url pattern="/**" access="authenticated"/>
|
||||
<cors/>
|
||||
</http>
|
||||
|
||||
<b:bean name="ep" class="org.springframework.security.web.authentication.HttpStatusEntryPoint">
|
||||
<b:constructor-arg value="I_AM_A_TEAPOT"/>
|
||||
</b:bean>
|
||||
|
||||
<b:bean name="preFlightRequestHandler"
|
||||
class="org.springframework.security.config.http.HttpCorsConfigTests.MyPreFlightRequestHandler"/>
|
||||
|
||||
<b:import resource="userservice.xml"/>
|
||||
</b:beans>
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user