1
0
mirror of synced 2026-07-09 21:00:02 +00:00

Compare commits

..

117 Commits

Author SHA1 Message Date
github-actions[bot] af2d210ccb Release 6.2.1 2023-12-18 15:21:01 +00:00
dependabot[bot] 69aeeeade7 Bump org.springframework.data:spring-data-bom from 2023.1.0 to 2023.1.1
Bumps [org.springframework.data:spring-data-bom](https://github.com/spring-projects/spring-data-bom) from 2023.1.0 to 2023.1.1.
- [Release notes](https://github.com/spring-projects/spring-data-bom/releases)
- [Commits](https://github.com/spring-projects/spring-data-bom/compare/2023.1.0...2023.1.1)

---
updated-dependencies:
- dependency-name: org.springframework.data:spring-data-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 08:13:10 -03:00
Leonardo V. C. Lima 4d3152894d Fix typo in Authorization Events' Doc Page 2023-12-15 17:39:44 -07:00
dependabot[bot] 4eae9f45e5 Bump org.springframework.ldap:spring-ldap-core from 3.2.0 to 3.2.1
Bumps [org.springframework.ldap:spring-ldap-core](https://github.com/spring-projects/spring-ldap) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/spring-projects/spring-ldap/releases)
- [Changelog](https://github.com/spring-projects/spring-ldap/blob/main/changelog.txt)
- [Commits](https://github.com/spring-projects/spring-ldap/compare/3.2.0...3.2.1)

---
updated-dependencies:
- dependency-name: org.springframework.ldap:spring-ldap-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 16:50:49 -07:00
Rob Winch c7047add5d Merge branch '6.1.x' into 6.2.x
Use CompositeFilterChainProxy
2023-12-15 01:16:21 -06:00
Rob Winch 142b268a21 Use CompositeFilterChainProxy
By extending FilterChainProxy CompositeFilterChainProxy is more passive since
users often depend on the type of the springSecurityFilterChain Bean being
FilterChainProxy (even though it can already be other types - when debug is
enabled).

Issue gh-14128
2023-12-15 01:15:38 -06:00
Rob Winch 6dd29520b0 Merge branch '6.1.x' into 6.2.x
Add HandlerMappingIntrospector Caching

Closes gh-14332
2023-12-14 16:10:50 -06:00
Rob Winch 70dfb3d391 Add HandlerMappingIntrospector Caching
Closes gh-14128
2023-12-14 16:08:36 -06:00
dependabot[bot] 0bd3b9e420 Bump Gamesight/slack-workflow-status from 1.0.1 to 1.2.0
Bumps [Gamesight/slack-workflow-status](https://github.com/gamesight/slack-workflow-status) from 1.0.1 to 1.2.0.
- [Release notes](https://github.com/gamesight/slack-workflow-status/releases)
- [Commits](https://github.com/gamesight/slack-workflow-status/compare/v1.0.1...v1.2.0)

---
updated-dependencies:
- dependency-name: Gamesight/slack-workflow-status
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 15:15:47 -03:00
Marcus Hert Da Coregio a162875f41 Merge branch '6.1.x' into 6.2.x 2023-12-14 15:15:24 -03:00
dependabot[bot] 1bb5fe409b Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 15:15:08 -03:00
Marcus Hert Da Coregio 6f0ce5c2b0 Merge branch '6.1.x' into 6.2.x 2023-12-14 15:05:04 -03:00
Marcus Hert Da Coregio 87e6986de5 Revert "Bump sjohnr/slack-workflow-status from 1.pre.beta to 1.1.0"
This reverts commit 40dd7a0d2d.
2023-12-14 15:04:02 -03:00
dependabot[bot] dce87beb07 Bump sjohnr/slack-workflow-status from 1.pre.beta to 1.1.0
Bumps [sjohnr/slack-workflow-status](https://github.com/sjohnr/slack-workflow-status) from 1.pre.beta to 1.1.0.
- [Commits](https://github.com/sjohnr/slack-workflow-status/compare/v1-beta...v1.1.0)

---
updated-dependencies:
- dependency-name: sjohnr/slack-workflow-status
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:05:20 -03:00
dependabot[bot] 6bede4cf7a Bump org.springframework:spring-framework-bom from 6.1.1 to 6.1.2
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.1 to 6.1.2.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.1...v6.1.2)

---
updated-dependencies:
- dependency-name: org.springframework:spring-framework-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:05:12 -03:00
dependabot[bot] 3c514bd747 Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:05:04 -03:00
dependabot[bot] 83585125ff Bump spring-io/spring-gradle-build-action from 1 to 2
Bumps [spring-io/spring-gradle-build-action](https://github.com/spring-io/spring-gradle-build-action) from 1 to 2.
- [Commits](https://github.com/spring-io/spring-gradle-build-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: spring-io/spring-gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:03:48 -03:00
dependabot[bot] 42432cc3de Bump slackapi/slack-github-action from 1.19.0 to 1.24.0
Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.19.0 to 1.24.0.
- [Release notes](https://github.com/slackapi/slack-github-action/releases)
- [Commits](https://github.com/slackapi/slack-github-action/compare/v1.19.0...v1.24.0)

---
updated-dependencies:
- dependency-name: slackapi/slack-github-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:03:37 -03:00
dependabot[bot] c9a7f2487c Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:03:26 -03:00
Marcus Hert Da Coregio 78aaaa7bce Merge branch '6.1.x' into 6.2.x 2023-12-14 09:01:37 -03:00
dependabot[bot] b2c3bc6b3a Bump spring-io/spring-gradle-build-action from 1 to 2
Bumps [spring-io/spring-gradle-build-action](https://github.com/spring-io/spring-gradle-build-action) from 1 to 2.
- [Commits](https://github.com/spring-io/spring-gradle-build-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: spring-io/spring-gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:01:21 -03:00
dependabot[bot] 652f98a88c Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:01:10 -03:00
dependabot[bot] fd02d7077d Bump org.springframework:spring-framework-bom from 6.0.14 to 6.0.15
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.0.14 to 6.0.15.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.14...v6.0.15)

---
updated-dependencies:
- dependency-name: org.springframework:spring-framework-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:01:02 -03:00
dependabot[bot] 40dd7a0d2d Bump sjohnr/slack-workflow-status from 1.pre.beta to 1.1.0
Bumps [sjohnr/slack-workflow-status](https://github.com/sjohnr/slack-workflow-status) from 1.pre.beta to 1.1.0.
- [Commits](https://github.com/sjohnr/slack-workflow-status/compare/v1-beta...v1.1.0)

---
updated-dependencies:
- dependency-name: sjohnr/slack-workflow-status
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:00:53 -03:00
dependabot[bot] 53b640e8e2 Bump slackapi/slack-github-action from 1.19.0 to 1.24.0
Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.19.0 to 1.24.0.
- [Release notes](https://github.com/slackapi/slack-github-action/releases)
- [Commits](https://github.com/slackapi/slack-github-action/compare/v1.19.0...v1.24.0)

---
updated-dependencies:
- dependency-name: slackapi/slack-github-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:00:31 -03:00
dependabot[bot] c6326062da Bump Gamesight/slack-workflow-status from 1.0.1 to 1.2.0
Bumps [Gamesight/slack-workflow-status](https://github.com/gamesight/slack-workflow-status) from 1.0.1 to 1.2.0.
- [Release notes](https://github.com/gamesight/slack-workflow-status/releases)
- [Commits](https://github.com/gamesight/slack-workflow-status/compare/v1.0.1...v1.2.0)

---
updated-dependencies:
- dependency-name: Gamesight/slack-workflow-status
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 09:00:22 -03:00
Marcus Hert Da Coregio 837189995d Merge branch '6.1.x' into 6.2.x 2023-12-14 08:59:18 -03:00
Marcus Hert Da Coregio 03e37e79ab Merge branch '5.8.x' into 6.1.x 2023-12-14 08:59:11 -03:00
dependabot[bot] 10b3a9b234 Bump Gamesight/slack-workflow-status from 1.0.1 to 1.2.0
Bumps [Gamesight/slack-workflow-status](https://github.com/gamesight/slack-workflow-status) from 1.0.1 to 1.2.0.
- [Release notes](https://github.com/gamesight/slack-workflow-status/releases)
- [Commits](https://github.com/gamesight/slack-workflow-status/compare/v1.0.1...v1.2.0)

---
updated-dependencies:
- dependency-name: Gamesight/slack-workflow-status
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 08:58:50 -03:00
dependabot[bot] e4cc0a4755 Bump slackapi/slack-github-action from 1.19.0 to 1.24.0
Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.19.0 to 1.24.0.
- [Release notes](https://github.com/slackapi/slack-github-action/releases)
- [Commits](https://github.com/slackapi/slack-github-action/compare/v1.19.0...v1.24.0)

---
updated-dependencies:
- dependency-name: slackapi/slack-github-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 08:58:37 -03:00
dependabot[bot] ff71ef46b7 Bump actions/setup-java from 3 to 4
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 08:58:19 -03:00
dependabot[bot] 5593655bbf Bump spring-io/spring-gradle-build-action from 1 to 2
Bumps [spring-io/spring-gradle-build-action](https://github.com/spring-io/spring-gradle-build-action) from 1 to 2.
- [Commits](https://github.com/spring-io/spring-gradle-build-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: spring-io/spring-gradle-build-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 08:58:09 -03:00
dependabot[bot] 47812e506f Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-14 08:58:00 -03:00
dependabot[bot] b03680ca58 Bump org-aspectj from 1.9.20.1 to 1.9.21
Bumps `org-aspectj` from 1.9.20.1 to 1.9.21.

Updates `org.aspectj:aspectjrt` from 1.9.20.1 to 1.9.21
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

Updates `org.aspectj:aspectjweaver` from 1.9.20.1 to 1.9.21
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

---
updated-dependencies:
- dependency-name: org.aspectj:aspectjrt
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.aspectj:aspectjweaver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:19:03 -03:00
dependabot[bot] d464c00315 Bump io.micrometer:micrometer-observation from 1.12.0 to 1.12.1
Bumps [io.micrometer:micrometer-observation](https://github.com/micrometer-metrics/micrometer) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.12.0...v1.12.1)

---
updated-dependencies:
- dependency-name: io.micrometer:micrometer-observation
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:18:53 -03:00
dependabot[bot] 17fbf396db Bump io.projectreactor:reactor-bom from 2023.0.0 to 2023.0.1
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2023.0.0 to 2023.0.1.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2023.0.0...2023.0.1)

---
updated-dependencies:
- dependency-name: io.projectreactor:reactor-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:18:44 -03:00
Marcus Hert Da Coregio 27c4ee3048 Merge branch '6.1.x' into 6.2.x 2023-12-13 09:18:03 -03:00
dependabot[bot] 426b61cd3c Bump org-aspectj from 1.9.20.1 to 1.9.21
Bumps `org-aspectj` from 1.9.20.1 to 1.9.21.

Updates `org.aspectj:aspectjrt` from 1.9.20.1 to 1.9.21
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

Updates `org.aspectj:aspectjweaver` from 1.9.20.1 to 1.9.21
- [Release notes](https://github.com/eclipse/org.aspectj/releases)
- [Commits](https://github.com/eclipse/org.aspectj/commits)

---
updated-dependencies:
- dependency-name: org.aspectj:aspectjrt
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.aspectj:aspectjweaver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:17:49 -03:00
dependabot[bot] 3f11908eac Bump io.projectreactor:reactor-bom from 2022.0.13 to 2022.0.14
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2022.0.13 to 2022.0.14.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2022.0.13...2022.0.14)

---
updated-dependencies:
- dependency-name: io.projectreactor:reactor-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:17:36 -03:00
Marcus Hert Da Coregio 986414fd4f Merge branch '6.1.x' into 6.2.x 2023-12-13 09:17:07 -03:00
Marcus Hert Da Coregio 4308b284a7 Merge branch '5.8.x' into 6.1.x 2023-12-13 09:16:58 -03:00
dependabot[bot] 89fd30f235 Bump io.projectreactor.netty:reactor-netty from 1.0.39 to 1.0.40
Bumps [io.projectreactor.netty:reactor-netty](https://github.com/reactor/reactor-netty) from 1.0.39 to 1.0.40.
- [Release notes](https://github.com/reactor/reactor-netty/releases)
- [Commits](https://github.com/reactor/reactor-netty/compare/v1.0.39...v1.0.40)

---
updated-dependencies:
- dependency-name: io.projectreactor.netty:reactor-netty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:16:42 -03:00
dependabot[bot] c3c068376a Bump io.projectreactor:reactor-bom from 2020.0.38 to 2020.0.39
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2020.0.38 to 2020.0.39.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2020.0.38...2020.0.39)

---
updated-dependencies:
- dependency-name: io.projectreactor:reactor-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 09:15:35 -03:00
Marcus Hert Da Coregio 4886951379 Merge branch '6.1.x' into 6.2.x
Closes gh-14295
2023-12-13 09:12:29 -03:00
Marcus Hert Da Coregio a650fe9e87 Merge branch '5.8.x' into 6.1.x
Closes gh-14294
2023-12-13 09:12:20 -03:00
Marcus Hert Da Coregio 6d68f403fc Document that Shibboleth Repository is Required for SAML Support
Closes gh-14286
2023-12-13 09:11:27 -03:00
Josh Cummings d130a18d3c Merge branch '6.1.x' into 6.2.x
Closes gh-14280
2023-12-11 11:45:16 -07:00
Josh Cummings f0772dc788 Merge branch '5.8.x' into 6.1.x
Closes gh-14279
2023-12-11 11:44:44 -07:00
Josh Cummings 74d06f020d Update to Latest Boot Property
Closes gh-14252
2023-12-11 11:44:08 -07:00
Josh Cummings 966c01fa90 Merge branch '6.1.x' into 6.2.x
Closes gh-14278
2023-12-11 10:21:00 -07:00
Josh Cummings c4a99fc942 Merge branch '5.8.x' into 6.1.x
Closes gh-14277
2023-12-11 10:20:38 -07:00
Candelario e896b14046 Dropped Nimbus Error Message
Closes gh-13730
2023-12-11 10:19:02 -07:00
Marcus Hert Da Coregio bdec2d3044 Use samplesBranch=6.2.x
Issue gh-14210
2023-12-11 09:45:09 -03:00
Josh Cummings 6e636e6abb Merge branch '6.1.x' into 6.2.x
Closes gh-14267
2023-12-09 11:50:58 -07:00
Josh Cummings 9f90661b6f Merge branch '5.8.x' into 6.1.x
Closes gh-14266
2023-12-09 11:43:04 -07:00
Josh Cummings be11812fe4 Account for Super-super-interface Inheritance
Closes gh-13625
2023-12-09 11:41:02 -07:00
Steve Riesenberg 981bc1e751 Merge branch '6.1.x' into 6.2.x 2023-12-07 14:39:29 -06:00
Steve Riesenberg 1783a70fdb Merge branch '5.8.x' into 6.1.x 2023-12-07 14:39:10 -06:00
Steve Riesenberg 9c44b700f5 Add Gradle Enterprise creds to PR builds
Closes gh-14249
2023-12-07 14:28:51 -06:00
Steve Riesenberg 32cf79d1a9 Merge branch '6.1.x' into 6.2.x 2023-12-07 11:37:20 -06:00
Steve Riesenberg bc648e0491 Remove unused apollo-runtime dependency
Closes gh-14259
2023-12-07 11:35:26 -06:00
dependabot[bot] 247a9fdabf Bump com.apollographql.apollo:apollo-runtime from 2.4.5 to 2.4.6
Bumps [com.apollographql.apollo:apollo-runtime](https://github.com/apollographql/apollo-android) from 2.4.5 to 2.4.6.
- [Release notes](https://github.com/apollographql/apollo-android/releases)
- [Changelog](https://github.com/apollographql/apollo-kotlin/blob/main/CHANGELOG.md)
- [Commits](https://github.com/apollographql/apollo-android/compare/v2.4.5...v2.4.6)

---
updated-dependencies:
- dependency-name: com.apollographql.apollo:apollo-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 11:15:16 -06:00
David Kanenwisher 4f6a4d6471 Fix typo in architecture.adoc 2023-12-07 11:03:43 -06:00
Steve Riesenberg 956438362d Merge branch '6.1.x' into 6.2.x 2023-12-05 18:05:55 -06:00
Steve Riesenberg a969f67c14 Merge branch '6.0.x' into 6.1.x 2023-12-05 18:05:39 -06:00
Steve Riesenberg c453c82948 Allow env vars to determine Artifactory repoKey
Closes gh-14250
2023-12-05 18:02:25 -06:00
Steve Riesenberg 674ce38bd3 Merge branch '6.1.x' 2023-12-05 13:36:55 -06:00
Steve Riesenberg 7aa6e0d787 Merge branch '6.0.x' into 6.1.x 2023-12-05 13:35:45 -06:00
Steve Riesenberg f6843b2bd9 Use env var to determine Artifactory URL
Closes gh-14246
2023-12-05 13:33:45 -06:00
Steve Riesenberg 15febfc65f Remove 6.0.x from scheduled releases 2023-12-04 16:02:46 -06:00
dependabot[bot] b5c43290e6 Bump ch.qos.logback:logback-classic from 1.4.13 to 1.4.14
Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.13 to 1.4.14.
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.13...v_1.4.14)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 11:26:48 -07:00
Josh Cummings d912914ea7 Merge branch '6.1.x' 2023-12-04 11:25:43 -07:00
dependabot[bot] aa732107dc Bump ch.qos.logback:logback-classic from 1.4.13 to 1.4.14
Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.13 to 1.4.14.
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.13...v_1.4.14)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 10:51:10 -07:00
Josh Cummings c540f885d3 Merge branch '6.1.x' 2023-12-04 10:18:33 -07:00
Josh Cummings f4314edc78 Merge branch '6.0.x' into 6.1.x 2023-12-04 10:18:07 -07:00
Josh Cummings 4e37499e28 Merge branch '5.8.x' into 6.0.x 2023-12-04 10:17:52 -07:00
dependabot[bot] 40e8b20257 Bump ch.qos.logback:logback-classic from 1.2.12 to 1.2.13
Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.2.12 to 1.2.13.
- [Commits](https://github.com/qos-ch/logback/compare/v_1.2.12...v_1.2.13)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 08:51:58 -07:00
Josh Cummings 3ab235cd56 Merge branch '6.1.x' 2023-12-01 15:54:44 -07:00
Josh Cummings 641722823e Merge branch '6.0.x' into 6.1.x 2023-12-01 15:45:32 -07:00
Josh Cummings f536b2652f Merge branch '5.8.x' into 6.0.x 2023-12-01 15:45:03 -07:00
Josh Cummings c336ca49fb Update Spring MVC Docs
Closes gh-14220
2023-12-01 12:57:46 -07:00
Josh Cummings c623303ca5 Add Logging
Now if the ServletRegistration API available message is shown, it will
also be accompanied with a startup warning in the logs.

Closes gh-14221
2023-12-01 12:57:46 -07:00
Josh Cummings a98baa7522 Polish ServletRegistration API Deferral
Tomcat uses different ServletContext instances from startup- and request-time.
This commit ensures that if the programmatic API isn't available at startup-time,
then use the ServletContext attached to the HttpServletRequest at runtime.

Issue gh-13794
2023-12-01 12:57:45 -07:00
dependabot[bot] b9b2df845f Bump com.unboundid:unboundid-ldapsdk from 6.0.10 to 6.0.11
Bumps [com.unboundid:unboundid-ldapsdk](https://github.com/pingidentity/ldapsdk) from 6.0.10 to 6.0.11.
- [Release notes](https://github.com/pingidentity/ldapsdk/releases)
- [Changelog](https://github.com/pingidentity/ldapsdk/blob/master/docs/release-notes.html)
- [Commits](https://github.com/pingidentity/ldapsdk/compare/6.0.10...6.0.11)

---
updated-dependencies:
- dependency-name: com.unboundid:unboundid-ldapsdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 11:40:10 -03:00
dependabot[bot] 4d07b9d632 Bump org.apache.maven:maven-resolver-provider from 3.9.5 to 3.9.6
Bumps [org.apache.maven:maven-resolver-provider](https://github.com/apache/maven) from 3.9.5 to 3.9.6.
- [Release notes](https://github.com/apache/maven/releases)
- [Commits](https://github.com/apache/maven/compare/maven-3.9.5...maven-3.9.6)

---
updated-dependencies:
- dependency-name: org.apache.maven:maven-resolver-provider
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 11:39:57 -03:00
Marcus Hert Da Coregio 1723d88bdf Merge branch '6.1.x' 2023-12-01 11:39:36 -03:00
dependabot[bot] 34c4b8904e Bump com.unboundid:unboundid-ldapsdk from 6.0.10 to 6.0.11
Bumps [com.unboundid:unboundid-ldapsdk](https://github.com/pingidentity/ldapsdk) from 6.0.10 to 6.0.11.
- [Release notes](https://github.com/pingidentity/ldapsdk/releases)
- [Changelog](https://github.com/pingidentity/ldapsdk/blob/master/docs/release-notes.html)
- [Commits](https://github.com/pingidentity/ldapsdk/compare/6.0.10...6.0.11)

---
updated-dependencies:
- dependency-name: com.unboundid:unboundid-ldapsdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 11:39:23 -03:00
Marcus Hert Da Coregio 6f45be28a0 Remove 6.0.x from Dependabot config
Closes gh-14227
2023-12-01 08:45:51 -03:00
Steve Riesenberg 8cdd53f531 Polish gh-13593 2023-11-30 13:23:13 -06:00
Seongguk Jeong 54b8f3874f Fix link in authentication/architecture.adoc
Closes gh-13577
2023-11-30 13:23:12 -06:00
dependabot[bot] a73c5d754a Bump ch.qos.logback:logback-classic from 1.4.11 to 1.4.13
Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.11 to 1.4.13.
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.11...v_1.4.13)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 13:07:15 -06:00
Steve Riesenberg 67424adef3 Merge branch '6.1.x' 2023-11-30 13:06:49 -06:00
dependabot[bot] 34cbf8ed10 Bump ch.qos.logback:logback-classic from 1.4.11 to 1.4.13
Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.11 to 1.4.13.
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.11...v_1.4.13)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 13:06:23 -06:00
Marcus Hert Da Coregio e9e198b1e3 Run Gradle Wrapper Upgrade on 6.1.x
Issue gh-14203
2023-11-30 16:00:29 -03:00
Marcus Hert Da Coregio 7c1e6f36c9 Merge branch '6.1.x' 2023-11-30 15:55:13 -03:00
github-actions[bot] 60d310e315 Bump Gradle Wrapper from 8.4 to 8.5 2023-11-30 15:54:57 -03:00
Steve Riesenberg 57f7eff568 Polish method-security.adoc 2023-11-30 12:18:57 -06:00
Steve Riesenberg 6e1605314a Polish gh-14219 2023-11-30 12:18:48 -06:00
ANDREI LISA 1d769b5afc make XML and Java/Kotlin consistent with AspectJExpressionPointcut 2023-11-30 12:14:27 -06:00
ahmd-nabil 0beda02a14 fix typo in docs and add api url
Signed-off-by: ahmd-nabil <ahm3dnabil99@gmail.com>
2023-11-30 09:12:14 -03:00
ahmd-nabil abe2029cb4 add missing [tabs] 2023-11-30 09:12:14 -03:00
Steve Riesenberg c2d88eca5a Merge branch '6.1.x' 2023-11-27 12:35:15 -06:00
Steve Riesenberg c0355884f3 Merge branch '6.0.x' into 6.1.x 2023-11-27 12:35:04 -06:00
Steve Riesenberg f25b3fba2f Disable automation to open new milestones on 6.0.x
Note: This change is only applied to 6.0.x and won't
be applied to newer branches.

Issue gh-13195

Closes gh-14203
2023-11-27 12:34:53 -06:00
Josh Cummings a4c107bd3c Correct What's New Link
Closes gh-14200
2023-11-27 10:02:17 -07:00
Marcus Hert Da Coregio d09ce0baff Merge branch '6.1.x' 2023-11-27 13:48:39 -03:00
Marcus Hert Da Coregio 008f0d413d Use samples branch 6.1.x 2023-11-27 13:48:16 -03:00
dependabot[bot] 515e8216b1 Bump org-apache-maven-resolver from 1.9.17 to 1.9.18
Bumps `org-apache-maven-resolver` from 1.9.17 to 1.9.18.

Updates `org.apache.maven.resolver:maven-resolver-connector-basic` from 1.9.17 to 1.9.18
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.17...maven-resolver-1.9.18)

Updates `org.apache.maven.resolver:maven-resolver-impl` from 1.9.17 to 1.9.18
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.17...maven-resolver-1.9.18)

Updates `org.apache.maven.resolver:maven-resolver-transport-http` from 1.9.17 to 1.9.18

---
updated-dependencies:
- dependency-name: org.apache.maven.resolver:maven-resolver-connector-basic
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.resolver:maven-resolver-impl
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.resolver:maven-resolver-transport-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 08:08:16 -03:00
dependabot[bot] d6ac0357fe Bump org.jetbrains.kotlin:kotlin-bom from 1.9.20 to 1.9.21
Bumps [org.jetbrains.kotlin:kotlin-bom](https://github.com/JetBrains/kotlin) from 1.9.20 to 1.9.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.20...v1.9.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 09:03:12 -03:00
dependabot[bot] c6265c5a7c Bump org.jetbrains.kotlin:kotlin-gradle-plugin from 1.9.20 to 1.9.21
Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.9.20 to 1.9.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.20...v1.9.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 09:03:01 -03:00
dependabot[bot] 5ef31c17da Bump org.hibernate.orm:hibernate-core from 6.3.1.Final to 6.3.2.Final
Bumps [org.hibernate.orm:hibernate-core](https://github.com/hibernate/hibernate-orm) from 6.3.1.Final to 6.3.2.Final.
- [Release notes](https://github.com/hibernate/hibernate-orm/releases)
- [Changelog](https://github.com/hibernate/hibernate-orm/blob/6.3.2/changelog.txt)
- [Commits](https://github.com/hibernate/hibernate-orm/compare/6.3.1...6.3.2)

---
updated-dependencies:
- dependency-name: org.hibernate.orm:hibernate-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 09:02:48 -03:00
dependabot[bot] 533ad7107f Bump org.springframework:spring-framework-bom from 6.1.0 to 6.1.1
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.0 to 6.1.1.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.0...v6.1.1)

---
updated-dependencies:
- dependency-name: org.springframework:spring-framework-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-24 09:02:35 -03:00
Parker Mauney 8e93e4715f Fix typo in getClaimAsMap docstring 2023-11-22 14:02:17 -03:00
aaron-to-go d99e98515c Fix typo in the 'Authorizing Requests' example
The example request matcher listed "/resources/**", while the explanation (3) used "/static/" instead.
2023-11-22 11:58:41 -03:00
dependabot[bot] ba851266c5 Bump org-apache-maven-resolver from 1.9.16 to 1.9.17
Bumps `org-apache-maven-resolver` from 1.9.16 to 1.9.17.

Updates `org.apache.maven.resolver:maven-resolver-connector-basic` from 1.9.16 to 1.9.17
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.16...maven-resolver-1.9.17)

Updates `org.apache.maven.resolver:maven-resolver-impl` from 1.9.16 to 1.9.17
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.16...maven-resolver-1.9.17)

Updates `org.apache.maven.resolver:maven-resolver-transport-http` from 1.9.16 to 1.9.17
- [Release notes](https://github.com/apache/maven-resolver/releases)
- [Commits](https://github.com/apache/maven-resolver/compare/maven-resolver-1.9.16...maven-resolver-1.9.17)

---
updated-dependencies:
- dependency-name: org.apache.maven.resolver:maven-resolver-connector-basic
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.resolver:maven-resolver-impl
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.resolver:maven-resolver-transport-http
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-22 11:57:21 -03:00
YangSiJun528 3f6b6aa523 Update Javadoc for getAuthorizationDecision method
Added missing description for `@return` tag.
2023-11-21 10:07:42 -03:00
github-actions[bot] 9749c23c74 Next development version 2023-11-20 15:51:09 +00:00
43 changed files with 1120 additions and 128 deletions
-20
View File
@@ -49,26 +49,6 @@ updates:
- dependency-name: "*"
update-types: [ "version-update:semver-major", "version-update:semver-minor" ]
- package-ecosystem: "gradle"
target-branch: "6.0.x"
milestone: 143 # 6.0.x
directory: "/"
schedule:
interval: "daily"
time: "03:00"
timezone: "Etc/UTC"
labels: [ "type: dependency-upgrade" ]
ignore:
- dependency-name: "com.nimbusds:nimbus-jose-jwt" # nimbus-jose-jwt gets updated when oauth2-oidc-sdk is updated to ensure consistency
- dependency-name: "org.python:jython" # jython updates break integration tests
- dependency-name: "org.apache.directory.server:*" # ApacheDS version > 1.5.5 contains break changes
- 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: "gradle"
target-branch: "5.8.x"
milestone: 246 # 5.8.x
@@ -32,7 +32,7 @@ jobs:
project_version: ${{ steps.continue.outputs.project_version }}
samples_branch: ${{ steps.continue.outputs.samples_branch }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- id: continue
name: Determine if should continue
run: |
@@ -52,9 +52,9 @@ jobs:
runs-on: ${{ matrix.os }}
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
@@ -82,9 +82,9 @@ jobs:
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
@@ -100,9 +100,9 @@ jobs:
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -125,9 +125,9 @@ jobs:
runs-on: ubuntu-latest
if: needs.prerequisites.outputs.runjobs
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -142,9 +142,9 @@ jobs:
needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -166,9 +166,9 @@ jobs:
needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -187,9 +187,9 @@ jobs:
needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -217,11 +217,11 @@ jobs:
TOKEN: ${{ github.token }}
VERSION: ${{ needs.prerequisites.outputs.project_version }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -254,7 +254,7 @@ jobs:
./gradlew createGitHubRelease -PnextVersion=$VERSION -Pbranch=$BRANCH -PcreateRelease=true -PgitHubAccessToken=$TOKEN
- name: Announce Release on Slack
id: spring-security-announcing
uses: slackapi/slack-github-action@v1.19.0
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
@@ -298,9 +298,9 @@ jobs:
TOKEN: ${{ github.token }}
VERSION: ${{ needs.prerequisites.outputs.project_version }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
if: github.repository_owner == 'spring-projects'
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ref: docs-build
fetch-depth: 1
@@ -20,7 +20,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
@@ -32,7 +32,7 @@ jobs:
actions: read
steps:
- name: Send Slack message
uses: Gamesight/slack-workflow-status@v1.0.1
uses: Gamesight/slack-workflow-status@v1.2.0
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
+7 -2
View File
@@ -2,6 +2,11 @@ name: PR Build
on: pull_request
env:
GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
permissions:
contents: read
@@ -11,9 +16,9 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.repository == 'spring-projects/spring-security' }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
+2 -2
View File
@@ -11,11 +11,11 @@ jobs:
strategy:
matrix:
# List of active maintenance branches.
branch: [ main, 6.1.x, 6.0.x, 5.8.x ]
branch: [ main, 6.1.x, 5.8.x ]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Dispatch
@@ -23,11 +23,11 @@ jobs:
steps:
- id: checkout-source
name: Checkout Source Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
- name: Set up gradle
uses: spring-io/spring-gradle-build-action@v1
uses: spring-io/spring-gradle-build-action@v2
with:
java-version: '17'
distribution: 'temurin'
@@ -72,7 +72,7 @@ jobs:
- id: send-slack-notification
name: Send Slack message
if: failure()
uses: Gamesight/slack-workflow-status@v1.0.1
uses: Gamesight/slack-workflow-status@v1.2.0
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
+1 -1
View File
@@ -169,7 +169,7 @@ wrapperUpgrade {
gradle {
'spring-security' {
repo = 'spring-projects/spring-security'
baseBranch = '6.0.x' // runs only on 6.0.x and the update is merged forward to main
baseBranch = '6.1.x' // runs only on 6.1.x and the update is merged forward to main
}
}
}
@@ -21,17 +21,38 @@ import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
class ArtifactoryPlugin implements Plugin<Project> {
private static final String ARTIFACTORY_URL_NAME = "ARTIFACTORY_URL"
private static final String ARTIFACTORY_SNAPSHOT_REPOSITORY = "ARTIFACTORY_SNAPSHOT_REPOSITORY"
private static final String ARTIFACTORY_MILESTONE_REPOSITORY = "ARTIFACTORY_MILESTONE_REPOSITORY"
private static final String ARTIFACTORY_RELEASE_REPOSITORY = "ARTIFACTORY_RELEASE_REPOSITORY"
private static final String DEFAULT_ARTIFACTORY_URL = "https://repo.spring.io"
private static final String DEFAULT_ARTIFACTORY_SNAPSHOT_REPOSITORY = "libs-snapshot-local"
private static final String DEFAULT_ARTIFACTORY_MILESTONE_REPOSITORY = "libs-milestone-local"
private static final String DEFAULT_ARTIFACTORY_RELEASE_REPOSITORY = "libs-release-local"
@Override
void apply(Project project) {
project.plugins.apply('com.jfrog.artifactory')
String name = Utils.getProjectName(project);
boolean isSnapshot = Utils.isSnapshot(project);
boolean isMilestone = Utils.isMilestone(project);
Map<String, String> env = System.getenv()
String artifactoryUrl = env.getOrDefault(ARTIFACTORY_URL_NAME, DEFAULT_ARTIFACTORY_URL)
String snapshotRepository = env.getOrDefault(ARTIFACTORY_SNAPSHOT_REPOSITORY, DEFAULT_ARTIFACTORY_SNAPSHOT_REPOSITORY)
String milestoneRepository = env.getOrDefault(ARTIFACTORY_MILESTONE_REPOSITORY, DEFAULT_ARTIFACTORY_MILESTONE_REPOSITORY)
String releaseRepository = env.getOrDefault(ARTIFACTORY_RELEASE_REPOSITORY, DEFAULT_ARTIFACTORY_RELEASE_REPOSITORY)
project.artifactory {
contextUrl = 'https://repo.spring.io'
contextUrl = artifactoryUrl
publish {
repository {
repoKey = isSnapshot ? 'libs-snapshot-local' : isMilestone ? 'libs-milestone-local' : 'libs-release-local'
repoKey = isSnapshot ? snapshotRepository : isMilestone ? milestoneRepository : releaseRepository
if(project.hasProperty('artifactoryUsername')) {
username = artifactoryUsername
password = artifactoryPassword
@@ -23,12 +23,14 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.function.Function;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
@@ -44,7 +46,6 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.function.SingletonSupplier;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@@ -76,6 +77,8 @@ public abstract class AbstractRequestMatcherRegistry<C> {
AbstractRequestMatcherRegistry.class.getClassLoader());
}
private final Log logger = LogFactory.getLog(getClass());
protected final void setApplicationContext(ApplicationContext context) {
this.context = context;
}
@@ -209,7 +212,12 @@ public abstract class AbstractRequestMatcherRegistry<C> {
matchers.add(resolve(ant, mvc, servletContext));
}
else {
matchers.add(new DeferredRequestMatcher(() -> resolve(ant, mvc, servletContext), mvc, ant));
this.logger
.warn("The ServletRegistration API was not available at startup time. This may be due to a misconfiguration; "
+ "if you are using AbstractSecurityWebApplicationInitializer, please double-check the recommendations outlined in "
+ "https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#abstractsecuritywebapplicationinitializer-with-spring-mvc");
matchers.add(new DeferredRequestMatcher((request) -> resolve(ant, mvc, request.getServletContext()),
mvc, ant));
}
}
return requestMatchers(matchers.toArray(new RequestMatcher[0]));
@@ -466,27 +474,34 @@ public abstract class AbstractRequestMatcherRegistry<C> {
static class DeferredRequestMatcher implements RequestMatcher {
final Supplier<RequestMatcher> requestMatcher;
final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory;
final AtomicReference<String> description = new AtomicReference<>();
DeferredRequestMatcher(Supplier<RequestMatcher> resolver, RequestMatcher... candidates) {
this.requestMatcher = SingletonSupplier.of(() -> {
RequestMatcher matcher = resolver.get();
this.description.set(matcher.toString());
return matcher;
});
volatile RequestMatcher requestMatcher;
DeferredRequestMatcher(Function<HttpServletRequest, RequestMatcher> resolver, RequestMatcher... candidates) {
this.requestMatcherFactory = (request) -> {
if (this.requestMatcher == null) {
synchronized (this) {
if (this.requestMatcher == null) {
this.requestMatcher = resolver.apply(request);
}
}
}
return this.requestMatcher;
};
this.description.set("Deferred " + Arrays.toString(candidates));
}
@Override
public boolean matches(HttpServletRequest request) {
return this.requestMatcher.get().matches(request);
return this.requestMatcherFactory.apply(request).matches(request);
}
@Override
public MatchResult matcher(HttpServletRequest request) {
return this.requestMatcher.get().matcher(request);
return this.requestMatcherFactory.apply(request).matcher(request);
}
@Override
@@ -49,6 +49,7 @@ import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.ObservationFilterChainDecorator;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer;
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
@@ -108,6 +109,8 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
private HttpServletRequestTransformer privilegeEvaluatorRequestTransformer;
private DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
private SecurityExpressionHandler<FilterInvocation> expressionHandler = this.defaultWebSecurityExpressionHandler;
@@ -350,6 +353,9 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
AuthorizationManagerWebInvocationPrivilegeEvaluator evaluator = new AuthorizationManagerWebInvocationPrivilegeEvaluator(
authorizationManager);
evaluator.setServletContext(this.servletContext);
if (this.privilegeEvaluatorRequestTransformer != null) {
evaluator.setRequestTransformer(this.privilegeEvaluatorRequestTransformer);
}
privilegeEvaluators.add(evaluator);
}
}
@@ -386,6 +392,9 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
}
catch (NoSuchBeanDefinitionException ex) {
}
Class<HttpServletRequestTransformer> requestTransformerClass = HttpServletRequestTransformer.class;
this.privilegeEvaluatorRequestTransformer = applicationContext.getBeanProvider(requestTransformerClass)
.getIfUnique();
}
@Override
@@ -16,9 +16,25 @@
package org.springframework.security.config.annotation.web.configuration;
import java.io.IOException;
import java.util.List;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
@@ -26,13 +42,21 @@ import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.BeanResolver;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.RequestRejectedHandler;
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;
import org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver;
import org.springframework.security.web.method.annotation.CurrentSecurityContextArgumentResolver;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
import org.springframework.web.filter.CompositeFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import org.springframework.web.servlet.support.RequestDataValueProcessor;
/**
@@ -50,6 +74,8 @@ import org.springframework.web.servlet.support.RequestDataValueProcessor;
*/
class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContextAware {
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
private BeanResolver beanResolver;
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
@@ -84,4 +110,198 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
}
}
/**
* Used to ensure Spring MVC request matching is cached.
*
* Creates a {@link BeanDefinitionRegistryPostProcessor} that detects if a bean named
* HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME is defined. If so, it moves the
* AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME to another bean name
* and then adds a {@link CompositeFilter} that contains
* {@link HandlerMappingIntrospector#createCacheFilter()} and the original
* FilterChainProxy under the original Bean name.
* @return
*/
@Bean
static BeanDefinitionRegistryPostProcessor springSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor() {
return new BeanDefinitionRegistryPostProcessor() {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (!registry.containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
return;
}
BeanDefinition hmiRequestTransformer = BeanDefinitionBuilder
.rootBeanDefinition(HandlerMappingIntrospectorRequestTransformer.class)
.addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)
.getBeanDefinition();
registry.registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer",
hmiRequestTransformer);
BeanDefinition filterChainProxy = registry
.getBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder
.rootBeanDefinition(HandlerMappingIntrospectorCachFilterFactoryBean.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ManagedList<BeanMetadataElement> filters = new ManagedList<>();
filters.add(hmiCacheFilterBldr.getBeanDefinition());
filters.add(filterChainProxy);
BeanDefinitionBuilder compositeSpringSecurityFilterChainBldr = BeanDefinitionBuilder
.rootBeanDefinition(CompositeFilterChainProxy.class)
.addConstructorArgValue(filters);
registry.removeBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
registry.registerBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME,
compositeSpringSecurityFilterChainBldr.getBeanDefinition());
}
};
}
/**
* {@link FactoryBean} to defer creation of
* {@link HandlerMappingIntrospector#createCacheFilter()}
*/
static class HandlerMappingIntrospectorCachFilterFactoryBean
implements ApplicationContextAware, FactoryBean<Filter> {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public Filter getObject() throws Exception {
HandlerMappingIntrospector handlerMappingIntrospector = this.applicationContext
.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
return handlerMappingIntrospector.createCacheFilter();
}
@Override
public Class<?> getObjectType() {
return Filter.class;
}
}
/**
* Extends {@link FilterChainProxy} to provide as much passivity as possible but
* delegates to {@link CompositeFilter} for
* {@link #doFilter(ServletRequest, ServletResponse, FilterChain)}.
*/
static class CompositeFilterChainProxy extends FilterChainProxy {
/**
* Used for {@link #doFilter(ServletRequest, ServletResponse, FilterChain)}
*/
private final Filter doFilterDelegate;
private final FilterChainProxy springSecurityFilterChain;
/**
* Creates a new instance
* @param filters the Filters to delegate to. One of which must be
* FilterChainProxy.
*/
CompositeFilterChainProxy(List<? extends Filter> filters) {
this.doFilterDelegate = createDoFilterDelegate(filters);
this.springSecurityFilterChain = findFilterChainProxy(filters);
}
@Override
public void afterPropertiesSet() {
this.springSecurityFilterChain.afterPropertiesSet();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
this.doFilterDelegate.doFilter(request, response, chain);
}
@Override
public List<Filter> getFilters(String url) {
return this.springSecurityFilterChain.getFilters(url);
}
@Override
public List<SecurityFilterChain> getFilterChains() {
return this.springSecurityFilterChain.getFilterChains();
}
@Override
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
this.springSecurityFilterChain.setSecurityContextHolderStrategy(securityContextHolderStrategy);
}
@Override
public void setFilterChainValidator(FilterChainValidator filterChainValidator) {
this.springSecurityFilterChain.setFilterChainValidator(filterChainValidator);
}
@Override
public void setFilterChainDecorator(FilterChainDecorator filterChainDecorator) {
this.springSecurityFilterChain.setFilterChainDecorator(filterChainDecorator);
}
@Override
public void setFirewall(HttpFirewall firewall) {
this.springSecurityFilterChain.setFirewall(firewall);
}
@Override
public void setRequestRejectedHandler(RequestRejectedHandler requestRejectedHandler) {
this.springSecurityFilterChain.setRequestRejectedHandler(requestRejectedHandler);
}
/**
* Used through reflection by Spring Security's Test support to lookup the
* FilterChainProxy Filters for a specific HttpServletRequest.
* @param request
* @return
*/
private List<? extends Filter> getFilters(HttpServletRequest request) {
List<SecurityFilterChain> filterChains = this.springSecurityFilterChain.getFilterChains();
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
/**
* Creates the Filter to delegate to for doFilter
* @param filters the Filters to delegate to.
* @return the Filter for doFilter
*/
private static Filter createDoFilterDelegate(List<? extends Filter> filters) {
CompositeFilter delegate = new CompositeFilter();
delegate.setFilters(filters);
return delegate;
}
/**
* Find the FilterChainProxy in a List of Filter
* @param filters
* @return non-null FilterChainProxy
* @throws IllegalStateException if the FilterChainProxy cannot be found
*/
private static FilterChainProxy findFilterChainProxy(List<? extends Filter> filters) {
for (Filter filter : filters) {
if (filter instanceof FilterChainProxy fcp) {
return fcp;
}
}
throw new IllegalStateException("Couldn't find FilterChainProxy in " + filters);
}
}
}
@@ -24,6 +24,7 @@ import jakarta.servlet.ServletRequest;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanReference;
@@ -36,6 +37,8 @@ import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
@@ -46,6 +49,7 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
import org.springframework.security.web.access.channel.ChannelDecisionManagerImpl;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.access.channel.InsecureChannelProcessor;
@@ -82,6 +86,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
/**
* Stateful class which helps HttpSecurityBDP to create the configuration for the
@@ -93,6 +98,11 @@ import org.springframework.util.xml.DomUtils;
*/
class HttpConfigurationBuilder {
private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
private static final boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
HttpConfigurationBuilder.class.getClassLoader());
private static final String ATT_CREATE_SESSION = "create-session";
private static final String ATT_SESSION_FIXATION_PROTECTION = "session-fixation-protection";
@@ -744,10 +754,14 @@ class HttpConfigurationBuilder {
// Create and register a AuthorizationManagerWebInvocationPrivilegeEvaluator for
// use with
// taglibs etc.
BeanDefinition wipe = BeanDefinitionBuilder
BeanDefinitionBuilder wipeBldr = BeanDefinitionBuilder
.rootBeanDefinition(AuthorizationManagerWebInvocationPrivilegeEvaluator.class)
.addConstructorArgReference(authorizationFilterParser.getAuthorizationManagerRef())
.getBeanDefinition();
.addConstructorArgReference(authorizationFilterParser.getAuthorizationManagerRef());
if (mvcPresent) {
wipeBldr.addPropertyValue("requestTransformer",
new RootBeanDefinition(HandlerMappingIntrospectorRequestTransformerFactoryBean.class));
}
BeanDefinition wipe = wipeBldr.getBeanDefinition();
this.pc.registerBeanComponent(
new BeanComponentDefinition(wipe, this.pc.getReaderContext().generateBeanName(wipe)));
this.fsi = new RuntimeBeanReference(fsiId);
@@ -913,6 +927,33 @@ class HttpConfigurationBuilder {
return BeanDefinitionBuilder.rootBeanDefinition(ObservationRegistryFactory.class).getBeanDefinition();
}
static class HandlerMappingIntrospectorRequestTransformerFactoryBean
implements FactoryBean<AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer>,
ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer getObject()
throws Exception {
HandlerMappingIntrospector hmi = this.applicationContext.getBeanProvider(HandlerMappingIntrospector.class)
.getIfAvailable();
return (hmi != null) ? new HandlerMappingIntrospectorRequestTransformer(hmi)
: AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer.IDENTITY;
}
@Override
public Class<?> getObjectType() {
return AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer.class;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
static class RoleVoterBeanFactory extends AbstractGrantedAuthorityDefaultsBeanFactory {
private RoleVoter voter = new RoleVoter();
@@ -307,7 +307,7 @@ public class AbstractRequestMatcherRegistryTests {
List<RequestMatcher> requestMatchers = new ArrayList<>();
for (RequestMatcher requestMatcher : wrappedMatchers) {
if (requestMatcher instanceof AbstractRequestMatcherRegistry.DeferredRequestMatcher) {
requestMatchers.add(((DeferredRequestMatcher) requestMatcher).requestMatcher.get());
requestMatchers.add(((DeferredRequestMatcher) requestMatcher).requestMatcher);
}
else {
requestMatchers.add(requestMatcher);
@@ -20,6 +20,7 @@ import java.io.IOException;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.ObservationTextPublisher;
import jakarta.servlet.Filter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.AfterEach;
@@ -39,7 +40,6 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.core.userdetails.PasswordEncodedUser;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
@@ -67,7 +67,7 @@ public class WebSecurityTests {
MockFilterChain chain;
@Autowired
FilterChainProxy springSecurityFilterChain;
Filter springSecurityFilterChain;
@BeforeEach
public void setup() {
@@ -0,0 +1,105 @@
/*
* 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.config.annotation.web.configuration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer;
import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Checks that HandlerMappingIntrospectorRequestTransformer is autowired into
* {@link org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator}.
*
* @author Rob Winch
*/
@ContextConfiguration
@WebAppConfiguration
@ExtendWith({ SpringExtension.class })
@SecurityTestExecutionListeners
public class AuthorizationManagerWebInvocationPrivilegeEvaluatorConfigTests {
public final SpringTestContext spring = new SpringTestContext(this);
@Autowired(required = false)
HttpServletRequestTransformer requestTransformer;
@Autowired
WebInvocationPrivilegeEvaluator wipe;
@Test
void mvcEnabledConfigThenHandlerMappingIntrospectorRequestTransformerBeanExists() {
this.spring.register(MvcEnabledConfig.class).autowire();
assertThat(this.requestTransformer).isInstanceOf(HandlerMappingIntrospectorRequestTransformer.class);
}
@Test
void mvcNotEnabledThenNoRequestTransformerBeanExists() {
this.spring.register(MvcNotEnabledConfig.class).autowire();
assertThat(this.requestTransformer).isNull();
}
@Test
void mvcNotEnabledAndTransformerThenWIPEDelegatesToTransformer() {
this.spring.register(MvcNotEnabledConfig.class, TransformerConfig.class).autowire();
this.wipe.isAllowed("/uri", TestAuthentication.authenticatedUser());
verify(this.requestTransformer).transform(any());
}
@Configuration
static class TransformerConfig {
@Bean
HttpServletRequestTransformer httpServletRequestTransformer() {
return mock(HttpServletRequestTransformer.class);
}
}
@Configuration
@EnableWebMvc
@EnableWebSecurity
static class MvcEnabledConfig {
}
@Configuration
@EnableWebSecurity
static class MvcNotEnabledConfig {
}
}
@@ -0,0 +1,127 @@
/*
* 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.config.annotation.web.configuration;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector.CachedResult;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
* @author Rob Winch
*/
@ContextConfiguration
@WebAppConfiguration
@ExtendWith({ SpringExtension.class })
@SecurityTestExecutionListeners
class HandlerMappingIntrospectorCacheFilterConfigTests {
@Autowired
WebApplicationContext context;
MockMvc mockMvc;
public final SpringTestContext spring = new SpringTestContext(this);
@Autowired(required = false)
MvcEnabledConfig.CaptureHandlerMappingIntrospectorCache captureCacheFilter;
@Autowired(required = false)
HandlerMappingIntrospector hmi;
@Test
@WithMockUser
void hmiIsCached() throws Exception {
this.spring.register(MvcEnabledConfig.class).autowire();
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(springSecurity())
.addFilter(this.captureCacheFilter)
.build();
this.mockMvc.perform(get("/"));
assertThat(this.captureCacheFilter.cachedResult).isNotNull();
}
@Test
@WithMockUser
void configurationLoadsIfNoHMI() {
// no BeanCreationException due to missing HandlerMappingIntrospector
this.spring.register(MvcNotEnabledConfig.class).autowire();
// ensure assumption of HandlerMappingIntrospector is null is true
assertThat(this.hmi).isNull();
}
@Configuration
@EnableWebMvc
@EnableWebSecurity
static class MvcEnabledConfig {
@Component
static class CaptureHandlerMappingIntrospectorCache implements Filter {
final HandlerMappingIntrospector hmi;
private CachedResult cachedResult;
CaptureHandlerMappingIntrospectorCache(HandlerMappingIntrospector hmi) {
this.hmi = hmi;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// capture the old cached value to check that caching has already occurred
this.cachedResult = this.hmi.setCache((HttpServletRequest) request);
chain.doFilter(request, response);
}
}
}
@Configuration
@EnableWebSecurity
static class MvcNotEnabledConfig {
}
}
@@ -67,7 +67,7 @@ public class AuthorizationEvent extends ApplicationEvent {
/**
* Get the response to the principal's request
* @return
* @return the response to the principal's request
*/
public AuthorizationDecision getAuthorizationDecision() {
return this.decision;
@@ -95,17 +95,28 @@ final class AuthorizationAnnotationUtils {
private static <A extends Annotation> boolean hasDuplicate(MergedAnnotations mergedAnnotations,
Class<A> annotationType) {
boolean alreadyFound = false;
MergedAnnotation<Annotation> alreadyFound = null;
for (MergedAnnotation<Annotation> mergedAnnotation : mergedAnnotations) {
if (isSynthetic(mergedAnnotation.getSource())) {
continue;
}
if (mergedAnnotation.getType() == annotationType) {
if (alreadyFound) {
return true;
}
alreadyFound = true;
if (mergedAnnotation.getType() != annotationType) {
continue;
}
if (alreadyFound == null) {
alreadyFound = mergedAnnotation;
continue;
}
// https://github.com/spring-projects/spring-framework/issues/31803
if (!mergedAnnotation.getSource().equals(alreadyFound.getSource())) {
return true;
}
if (mergedAnnotation.getRoot().getType() != alreadyFound.getRoot().getType()) {
return true;
}
}
return false;
@@ -41,6 +41,13 @@ class AuthorizationAnnotationUtilsTests {
.isThrownBy(() -> AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreAuthorize.class));
}
@Test // gh-13625
void annotationsFromSuperSuperInterfaceShouldNotTriggerAnnotationConfigurationException() throws Exception {
Method method = HelloImpl.class.getMethod("sayHello");
assertThatNoException()
.isThrownBy(() -> AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreAuthorize.class));
}
private interface BaseRepository<T> {
Iterable<T> findAll();
@@ -55,4 +62,24 @@ class AuthorizationAnnotationUtilsTests {
}
private interface Hello {
@PreAuthorize("hasRole('someRole')")
String sayHello();
}
private interface SayHello extends Hello {
}
private static class HelloImpl implements SayHello {
@Override
public String sayHello() {
return "hello";
}
}
}
@@ -434,7 +434,7 @@ spring:
oauth2:
resourceserver:
jwt:
jws-algorithm: RS512
jws-algorithms: RS512
jwk-set-uri: https://idp.example.org/.well-known/jwks.json
----
@@ -281,7 +281,7 @@ To do that, you can configure your application to <<servlet-logging,log the secu
[[adding-custom-filter]]
=== Adding a Custom Filter to the Filter Chain
Mostly of the times, the default security filters are enough to provide security to your application.
Most of the time, the default security filters are enough to provide security to your application.
However, there might be times that you want to add a custom `Filter` to the security filter chain.
For example, let's say that you want to add a `Filter` that gets a tenant id header and check if the current user has access to that tenant.
@@ -336,7 +336,7 @@ Instead of implementing `Filter`, you can extend from {spring-framework-api-url}
====
Now, we need to add the filter to the security filter chain.
[tabs]
======
Java::
+
@@ -161,7 +161,7 @@ Of course, Spring Security is expressly designed to handle this common requireme
== AuthenticationManager
{security-api-url}org/springframework/security/authentication/AuthenticationManager.html[`AuthenticationManager`] is the API that defines how Spring Security's Filters perform xref:features/authentication/index.adoc#authentication[authentication].
The <<servlet-authentication-authentication,`Authentication`>> that is returned is then set on the <<servlet-authentication-securitycontextholder>> by the controller (that is, by <<servlet-security-filters,Spring Security's `Filters` instances>>) that invoked the `AuthenticationManager`.
The <<servlet-authentication-authentication,`Authentication`>> that is returned is then set on the <<servlet-authentication-securitycontextholder>> by the controller (that is, by xref:servlet/architecture.adoc#servlet-security-filters[Spring Security's `Filters` instances]) that invoked the `AuthenticationManager`.
If you are not integrating with Spring Security's `Filters` instances, you can set the `SecurityContextHolder` directly and are not required to use an `AuthenticationManager`.
While the implementation of `AuthenticationManager` could be anything, the most common implementation is <<servlet-authentication-providermanager,`ProviderManager`>>.
@@ -145,7 +145,7 @@ Many sites allow certain limited access under remember-me authentication, but re
[[authz-authorization-managers]]
==== AuthorizationManagers
There are also helpful static factories in `AuthenticationManagers` for composing individual ``AuthenticationManager``s into more sophisticated expressions.
There are also helpful static factories in {security-api-url}org/springframework/security/authorization/AuthorizationManagers.html[`AuthorizationManagers`] for composing individual ``AuthorizationManager``s into more sophisticated expressions.
[[authz-custom-authorization-manager]]
==== Custom Authorization Managers
@@ -749,7 +749,7 @@ SecurityFilterChain web(HttpSecurity http) throws Exception {
Each rule is considered in the order they were declared.
<2> Dispatches `FORWARD` and `ERROR` are permitted to allow {spring-framework-reference-url}web.html#spring-web[Spring MVC] to render views and Spring Boot to render errors
<3> We specified multiple URL patterns that any user can access.
Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
Specifically, any user can access a request if the URL starts with "/static/", equals "/signup", or equals "/about".
<4> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix.
<5> Any URL that starts with "/db/" requires the user to have both been granted the "db" permission as well as be a "ROLE_ADMIN".
@@ -2,7 +2,7 @@
= Authorization Events
For each authorization that is denied, an `AuthorizationDeniedEvent` is fired.
Also, it's possible to fire and `AuthorizationGrantedEvent` for authorizations that are granted.
Also, it's possible to fire an `AuthorizationGrantedEvent` for authorizations that are granted.
To listen for these events, you must first publish an `AuthorizationEventPublisher`.
@@ -1214,9 +1214,9 @@ Kotlin::
companion object {
@Bean
fun methodSecurityExpressionHandler(val roleHierarchy: RoleHierarchy) : MethodSecurityExpressionHandler {
val handler = DefaultMethodSecurityExpressionHandler();
handler.setRoleHierarchy(roleHierarchy);
return handler;
val handler = DefaultMethodSecurityExpressionHandler()
handler.setRoleHierarchy(roleHierarchy)
return handler
}
}
----
@@ -1260,14 +1260,14 @@ Java::
+
[source,java,role="primary"]
----
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole;
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static Advisor protectServicePointcut() {
JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut();
pattern.setPattern("execution(* com.mycompany.*Service.*(..))");
return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER"));
AspectJExpressionPointcut pattern = new AspectJExpressionPointcut()
pattern.setExpression("execution(* com.mycompany.*Service.*(..))")
return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER"))
}
----
@@ -1275,26 +1275,28 @@ Kotlin::
+
[source,kotlin,role="secondary"]
----
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole;
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole
companion object {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun protectServicePointcut(): Advisor {
var pattern = JdkRegexpMethodPointcut();
pattern.setPattern("execution(* com.mycompany.*Service.*(..))");
return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER"));
val pattern = AspectJExpressionPointcut()
pattern.setExpression("execution(* com.mycompany.*Service.*(..))")
return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER"))
}
}
----
======
[source,xml]
Xml::
+
[source,xml,role="secondary"]
----
<sec:method-security>
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="hasRole('USER')"/>
</sec:method-security>
----
======
[[weave-aspectj]]
=== Integrate with AspectJ Byte-weaving
@@ -1445,7 +1447,7 @@ open class MyService {
fun readResource(...): MyResource
@PreAuthorize("@authz.check(#root)")
fun shareResource(...): MyResource;
fun shareResource(...): MyResource
}
----
@@ -1769,8 +1771,8 @@ class MyExpressionHandler: DefaultMethodSecurityExpressionHandler {
val context = super.createEvaluationContext(authentication, mi) as StandardEvaluationContext
val delegate = context.getRootObject().getValue() as MethodSecurityExpressionOperations
val root = MySecurityExpressionRoot(delegate)
context.setRootObject(root);
return context;
context.setRootObject(root)
return context
}
}
----
@@ -114,7 +114,7 @@ public class SecurityWebApplicationInitializer
This onlys register the `springSecurityFilterChain` for every URL in your application.
After that, we need to ensure that `WebSecurityConfig` was loaded in our existing `ApplicationInitializer`.
For example, if we use Spring MVC it is added in the `getRootConfigClasses()`:
For example, if we use Spring MVC it is added in the `getServletConfigClasses()`:
[[message-web-application-inititializer-java]]
[source,java]
@@ -123,14 +123,42 @@ public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class };
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebSecurityConfig.class, WebMvcConfig.class };
}
// ... other overrides ...
}
----
The reason for this is that Spring Security needs to be able to inspect some Spring MVC configuration in order to appropriately configure xref:servlet/authorization/authorize-http-requests.adoc#_request_matchers[underlying request matchers], so they need to be in the same application context.
Placing Spring Security in `getRootConfigClasses` places it into a parent application context that may not be able to find Spring MVC's `HandlerMappingIntrospector`.
==== Configuring for Multiple Spring MVC Dispatchers
If desired, any Spring Security configuration that is unrelated to Spring MVC may be placed in a different configuration class like so:
[source,java]
----
public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { NonWebSecurityConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebSecurityConfig.class, WebMvcConfig.class };
}
// ... other overrides ...
}
----
This can be helpful if you have multiple instances of `AbstractAnnotationConfigDispatcherServletInitializer` and don't want to duplicate the general security configuration across both of them.
[[jc-httpsecurity]]
== HttpSecurity
@@ -574,7 +574,7 @@ spring:
oauth2:
resourceserver:
jwt:
jws-algorithm: RS512
jws-algorithms: RS512
jwk-set-uri: https://idp.example.org/.well-known/jwks.json
----
@@ -63,7 +63,42 @@ image:{icondir}/number_4.png[] If authentication is successful, then _Success_.
== Minimal Dependencies
SAML 2.0 service provider support resides in `spring-security-saml2-service-provider`.
It builds off of the OpenSAML library.
It builds off of the OpenSAML library, and, for that reason, you must also include the Shibboleth Maven repository in your build configuration.
Check https://shibboleth.atlassian.net/wiki/spaces/DEV/pages/1123844333/Use+of+Maven+Central#Publishing-to-Maven-Central[this link] for more details about why a separate repository is needed.
[tabs]
======
Maven::
+
[source,xml,role="primary"]
----
<repositories>
<!-- ... -->
<repository>
<id>shibboleth-releases</id>
<url>https://build.shibboleth.net/nexus/content/repositories/releases/</url>
</repository>
</repositories>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
----
Gradle::
+
[source,groovy,role="secondary"]
----
repositories {
// ...
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
// ...
implementation 'org.springframework.security:spring-security-saml2-service-provider'
}
----
======
[[servlet-saml2login-minimalconfiguration]]
== Minimal Configuration
+1 -1
View File
@@ -9,7 +9,7 @@ Below are the highlights of the release.
* https://github.com/spring-projects/spring-security/issues/5011[gh-5011] - xref:servlet/integrations/cors.adoc[(docs)] Automatically enable `.cors()` if `CorsConfigurationSource` bean is present
* https://github.com/spring-projects/spring-security/issues/13204[gh-13204] - xref:migration-7/configuration.adoc#_use_with_instead_of_apply_for_custom_dsls[(docs)] Add `AbstractConfiguredSecurityBuilder.with(...)` method to apply configurers returning the builder
* https://github.com/spring-projects/spring-security/pull/13587[gh-13587] - https://spring.io/blog/2023/08/22/tackling-the-oauth2-client-component-model-in-spring-security/[blog post] Simplify configuration of OAuth2 Client component model
* https://github.com/spring-projects/spring-security/pull/13857[gh-13857] - xref:servlet/authorization/authorize-http-requests.adoc#match-by-mvc[docs] Add servlet pattern support to AuthorizeHttpRequests
* https://github.com/spring-projects/spring-security/issues/13666[gh-13666], https://github.com/spring-projects/spring-security/pull/13667[gh-13667], https://github.com/spring-projects/spring-security/issues/13726[gh-13726], https://github.com/spring-projects/spring-security/issues/13850[gh-13850] - xref:servlet/authorization/authorize-http-requests.adoc#match-by-mvc[docs] Improved CVE-2023-34035 detection
== OAuth 2.0/OIDC
+2 -2
View File
@@ -1,6 +1,6 @@
springBootVersion=3.1.1
version=6.2.0
samplesBranch=main
version=6.2.1
samplesBranch=6.2.x
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
+13 -14
View File
@@ -5,18 +5,18 @@ io-spring-javaformat = "0.0.40"
io-spring-nohttp = "0.0.11"
jakarta-websocket = "2.1.1"
org-apache-directory-server = "1.5.5"
org-apache-maven-resolver = "1.9.16"
org-aspectj = "1.9.20.1"
org-apache-maven-resolver = "1.9.18"
org-aspectj = "1.9.21"
org-bouncycastle = "1.70"
org-eclipse-jetty = "11.0.18"
org-jetbrains-kotlin = "1.9.20"
org-jetbrains-kotlin = "1.9.21"
org-jetbrains-kotlinx = "1.7.3"
org-mockito = "5.5.0"
org-opensaml = "4.3.0"
org-springframework = "6.1.0"
org-springframework = "6.1.2"
[libraries]
ch-qos-logback-logback-classic = "ch.qos.logback:logback-classic:1.4.11"
ch-qos-logback-logback-classic = "ch.qos.logback:logback-classic:1.4.14"
com-fasterxml-jackson-jackson-bom = "com.fasterxml.jackson:jackson-bom:2.15.3"
com-google-inject-guice = "com.google.inject:guice:3.0"
com-netflix-nebula-nebula-project-plugin = "com.netflix.nebula:nebula-project-plugin:8.2.0"
@@ -24,11 +24,11 @@ com-nimbusds-nimbus-jose-jwt = "com.nimbusds:nimbus-jose-jwt:9.24.4"
com-nimbusds-oauth2-oidc-sdk = "com.nimbusds:oauth2-oidc-sdk:9.43.3"
com-squareup-okhttp3-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "com-squareup-okhttp3" }
com-squareup-okhttp3-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "com-squareup-okhttp3" }
com-unboundid-unboundid-ldapsdk = "com.unboundid:unboundid-ldapsdk:6.0.10"
com-unboundid-unboundid-ldapsdk = "com.unboundid:unboundid-ldapsdk:6.0.11"
commons-collections = "commons-collections:commons-collections:3.2.2"
io-micrometer-micrometer-observation = "io.micrometer:micrometer-observation:1.12.0"
io-micrometer-micrometer-observation = "io.micrometer:micrometer-observation:1.12.1"
io-mockk = "io.mockk:mockk:1.13.8"
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.0"
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.1"
io-rsocket-rsocket-bom = { module = "io.rsocket:rsocket-bom", version.ref = "io-rsocket" }
io-spring-javaformat-spring-javaformat-checkstyle = { module = "io.spring.javaformat:spring-javaformat-checkstyle", version.ref = "io-spring-javaformat" }
io-spring-javaformat-spring-javaformat-gradle-plugin = { module = "io.spring.javaformat:spring-javaformat-gradle-plugin", version.ref = "io-spring-javaformat" }
@@ -52,7 +52,7 @@ org-apache-directory-server-apacheds-protocol-shared = { module = "org.apache.di
org-apache-directory-server-apacheds-server-jndi = { module = "org.apache.directory.server:apacheds-server-jndi", version.ref = "org-apache-directory-server" }
org-apache-directory-shared-shared-ldap = "org.apache.directory.shared:shared-ldap:0.9.15"
org-apache-httpcomponents-httpclient = "org.apache.httpcomponents:httpclient:4.5.14"
org-apache-maven-maven-resolver-provider = "org.apache.maven:maven-resolver-provider:3.9.5"
org-apache-maven-maven-resolver-provider = "org.apache.maven:maven-resolver-provider:3.9.6"
org-apache-maven-resolver-maven-resolver-connector-basic = { module = "org.apache.maven.resolver:maven-resolver-connector-basic", version.ref = "org-apache-maven-resolver" }
org-apache-maven-resolver-maven-resolver-impl = { module = "org.apache.maven.resolver:maven-resolver-impl", version.ref = "org-apache-maven-resolver" }
org-apache-maven-resolver-maven-resolver-transport-http = { module = "org.apache.maven.resolver:maven-resolver-transport-http", version.ref = "org-apache-maven-resolver" }
@@ -66,10 +66,10 @@ org-bouncycastle-bcprov-jdk15on = { module = "org.bouncycastle:bcprov-jdk15on",
org-eclipse-jetty-jetty-server = { module = "org.eclipse.jetty:jetty-server", version.ref = "org-eclipse-jetty" }
org-eclipse-jetty-jetty-servlet = { module = "org.eclipse.jetty:jetty-servlet", version.ref = "org-eclipse-jetty" }
org-hamcrest = "org.hamcrest:hamcrest:2.2"
org-hibernate-orm-hibernate-core = "org.hibernate.orm:hibernate-core:6.3.1.Final"
org-hibernate-orm-hibernate-core = "org.hibernate.orm:hibernate-core:6.3.2.Final"
org-hsqldb = "org.hsqldb:hsqldb:2.7.2"
org-jetbrains-kotlin-kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "org-jetbrains-kotlin" }
org-jetbrains-kotlin-kotlin-gradle-plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20"
org-jetbrains-kotlin-kotlin-gradle-plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21"
org-jetbrains-kotlinx-kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "org-jetbrains-kotlinx" }
org-junit-junit-bom = "org.junit:junit-bom:5.10.1"
org-mockito-mockito-bom = { module = "org.mockito:mockito-bom", version.ref = "org-mockito" }
@@ -83,8 +83,8 @@ org-seleniumhq-selenium-selenium-support = "org.seleniumhq.selenium:selenium-sup
org-skyscreamer-jsonassert = "org.skyscreamer:jsonassert:1.5.1"
org-slf4j-log4j-over-slf4j = "org.slf4j:log4j-over-slf4j:1.7.36"
org-slf4j-slf4j-api = "org.slf4j:slf4j-api:2.0.9"
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2023.1.0"
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.0"
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2023.1.1"
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.1"
org-springframework-spring-framework-bom = { module = "org.springframework:spring-framework-bom", version.ref = "org-springframework" }
org-synchronoss-cloud-nio-multipart-parser = "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
@@ -95,7 +95,6 @@ org-yaml-snakeyaml = "org.yaml:snakeyaml:1.30"
org-apache-commons-commons-io = "org.apache.commons:commons-io:1.3.2"
io-github-gradle-nexus-publish-plugin = "io.github.gradle-nexus:publish-plugin:1.1.0"
org-gretty-gretty = "org.gretty:gretty:4.0.3"
com-apollographql-apollo-apollo-runtime = "com.apollographql.apollo:apollo-runtime:2.4.5"
com-github-ben-manes-gradle-versions-plugin = "com.github.ben-manes:gradle-versions-plugin:0.38.0"
com-github-spullara-mustache-java-compiler = "com.github.spullara.mustache.java:compiler:0.9.11"
org-hidetake-gradle-ssh-plugin = "org.hidetake:gradle-ssh-plugin:2.10.1"
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
@@ -134,7 +134,7 @@ public interface ClaimAccessor {
* @param claim the name of the claim
* @return the claim value or {@code null} if the claim does not exist
* @throws IllegalArgumentException if the claim value cannot be converted to a
* {@code List}
* {@code Map}
* @throws NullPointerException if the claim value is {@code null}
*/
@SuppressWarnings("unchecked")
@@ -145,6 +145,9 @@ public final class NimbusJwtDecoder implements JwtDecoder {
}
catch (Exception ex) {
this.logger.trace("Failed to parse token", ex);
if (ex instanceof ParseException) {
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed token"), ex);
}
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
}
}
@@ -100,6 +100,8 @@ public class NimbusJwtDecoderTests {
private static final String JWK_SET = "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"one\",\"n\":\"oXJ8OyOv_eRnce4akdanR4KYRfnC2zLV4uYNQpcFn6oHL0dj7D6kxQmsXoYgJV8ZVDn71KGmuLvolxsDncc2UrhyMBY6DVQVgMSVYaPCTgW76iYEKGgzTEw5IBRQL9w3SRJWd3VJTZZQjkXef48Ocz06PGF3lhbz4t5UEZtdF4rIe7u-977QwHuh7yRPBQ3sII-cVoOUMgaXB9SHcGF2iZCtPzL_IffDUcfhLQteGebhW8A6eUHgpD5A1PQ-JCw_G7UOzZAjjDjtNM2eqm8j-Ms_gqnm4MiCZ4E-9pDN77CAAPVN7kuX6ejs9KBXpk01z48i9fORYk9u7rAkh1HuQw\"}]}";
private static final String MALFORMED_TOKEN = "eyJhbGciOiJSUzI1NiJ9.eyJuYmYiOnt9LCJleHAiOjQ2ODQyMjUwODd9";
private static final String NEW_KID_JWK_SET = "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"kid\":\"two\",\"n\":\"ra9UJw4I0fCHuOqr1xWJsh-qcVeZWtKEU3uoqq1sAg5fG67dujNCm_Q16yuO0ZdDiU0vlJkbc_MXFAvm4ZxdJ_qR7PAneV-BOGNtLpSaiPclscCy3m7zjRWkaqwt9ZZEsdK5UqXyPlBpcYhNKsmnQGjnX4sYb7d8b2jSCM_qto48-6451rbyEhXXywtFy_JqtTpbsw_IIdQHMr1O-MdSjsQxX9kkvZwPU8LsC-CcqlcsZ7mnpOhmIXaf4tbRwAaluXwYft0yykFsp8e5C4t9mMs9Vu8AB5gT8o-D_ovXd2qh4k3ejzVpYLtzD4nbfvPJA_TXmjhn-9GOPAqkzfON2Q\"}]}";
private static final String MALFORMED_JWK_SET = "malformed";
@@ -195,6 +197,12 @@ public class NimbusJwtDecoderTests {
// @formatter:on
}
@Test
public void decodeWhenTokenMalformedThenReturnsMalformedTokenMessage() {
assertThatExceptionOfType(BadJwtException.class).isThrownBy(() -> this.jwtDecoder.decode(MALFORMED_TOKEN))
.withMessage("An error occurred while attempting to decode the Jwt: Malformed token");
}
@Test
public void decodeWhenJwtFailsValidationThenReturnsCorrespondingErrorMessage() {
OAuth2Error failure = new OAuth2Error("mock-error", "mock-description", "mock-uri");
@@ -40,6 +40,8 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
private ServletContext servletContext;
private HttpServletRequestTransformer requestTransformer = HttpServletRequestTransformer.IDENTITY;
public AuthorizationManagerWebInvocationPrivilegeEvaluator(
AuthorizationManager<HttpServletRequest> authorizationManager) {
Assert.notNull(authorizationManager, "authorizationManager cannot be null");
@@ -54,8 +56,8 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
@Override
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
AuthorizationDecision decision = this.authorizationManager.check(() -> authentication,
filterInvocation.getHttpRequest());
HttpServletRequest httpRequest = this.requestTransformer.transform(filterInvocation.getHttpRequest());
AuthorizationDecision decision = this.authorizationManager.check(() -> authentication, httpRequest);
return decision == null || decision.isGranted();
}
@@ -64,4 +66,34 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
this.servletContext = servletContext;
}
/**
* Set a {@link HttpServletRequestTransformer} to be used prior to passing to the
* {@link AuthorizationManager}.
* @param requestTransformer the {@link HttpServletRequestTransformer} to use.
*/
public void setRequestTransformer(HttpServletRequestTransformer requestTransformer) {
Assert.notNull(requestTransformer, "requestTransformer cannot be null");
this.requestTransformer = requestTransformer;
}
/**
* Used to transform the {@link HttpServletRequest} prior to passing it into the
* {@link AuthorizationManager}.
*/
public interface HttpServletRequestTransformer {
HttpServletRequestTransformer IDENTITY = (request) -> request;
/**
* Return the {@link HttpServletRequest} that is passed into the
* {@link AuthorizationManager}
* @param request the {@link HttpServletRequest} created by the
* {@link WebInvocationPrivilegeEvaluator}
* @return the {@link HttpServletRequest} that is passed into the
* {@link AuthorizationManager}
*/
HttpServletRequest transform(HttpServletRequest request);
}
}
@@ -0,0 +1,96 @@
/*
* 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.access;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.Assert;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
/**
* Transforms by passing it into
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)}. Before, it wraps the
* {@link HttpServletRequest} to ensure that the methods needed work since some methods by
* default throw {@link UnsupportedOperationException}.
*
* @author Rob Winch
*/
public class HandlerMappingIntrospectorRequestTransformer
implements AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer {
private final HandlerMappingIntrospector introspector;
public HandlerMappingIntrospectorRequestTransformer(HandlerMappingIntrospector introspector) {
Assert.notNull(introspector, "introspector canot be null");
this.introspector = introspector;
}
@Override
public HttpServletRequest transform(HttpServletRequest request) {
CacheableRequestWrapper cacheableRequest = new CacheableRequestWrapper(request);
this.introspector.setCache(cacheableRequest);
return cacheableRequest;
}
static final class CacheableRequestWrapper extends HttpServletRequestWrapper {
private final Map<String, Object> attributes = new HashMap<>();
/**
* Constructs a request object wrapping the given request.
* @param request the {@link HttpServletRequest} to be wrapped.
* @throws IllegalArgumentException if the request is null
*/
CacheableRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public DispatcherType getDispatcherType() {
return DispatcherType.REQUEST;
}
@Override
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
}
@Override
public Object getAttribute(String name) {
return this.attributes.get(name);
}
@Override
public void setAttribute(String name, Object o) {
this.attributes.put(name, o);
}
@Override
public void removeAttribute(String name) {
this.attributes.remove(name);
}
}
}
@@ -25,14 +25,17 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator.HttpServletRequestTransformer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
@@ -45,6 +48,9 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
@Mock
private AuthorizationManager<HttpServletRequest> authorizationManager;
@Mock
private HttpServletRequestTransformer requestTransformer;
@Test
void constructorWhenAuthorizationManagerNullThenIllegalArgument() {
assertThatIllegalArgumentException()
@@ -84,4 +90,20 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
assertThat(captor.getValue().getServletContext()).isSameAs(servletContext);
}
@Test
void setRequestTransformerWhenNullThenIllegalArgumentException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.privilegeEvaluator.setRequestTransformer(null));
}
@Test
void isAllowedWhenRequestTransformerThenUsesRequestTransformerResult() {
HttpServletRequest request = new MockHttpServletRequest();
given(this.requestTransformer.transform(any())).willReturn(request);
this.privilegeEvaluator.setRequestTransformer(this.requestTransformer);
this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
verify(this.authorizationManager).check(any(), eq(request));
}
}
@@ -0,0 +1,206 @@
/*
* 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.access;
import java.util.Collections;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.http.HttpServletRequest;
import org.assertj.core.api.AssertionsForClassTypes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
/**
* @author Rob Winch
*/
@ExtendWith(MockitoExtension.class)
class HandlerMappingIntrospectorRequestTransformerTests {
@Mock
HandlerMappingIntrospector hmi;
HandlerMappingIntrospectorRequestTransformer transformer;
@BeforeEach
void setup() {
this.transformer = new HandlerMappingIntrospectorRequestTransformer(this.hmi);
}
@Test
void constructorWhenHmiIsNullThenIllegalArgumentException() {
AssertionsForClassTypes.assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new HandlerMappingIntrospectorRequestTransformer(null));
}
@Test
void transformThenNewRequestPassedToSetCache() {
MockHttpServletRequest request = new MockHttpServletRequest();
HttpServletRequest transformedRequest = this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
assertThat(transformedRequest).isNotEqualTo(request);
}
@Test
void transformThenResultPassedToSetCache() {
MockHttpServletRequest request = new MockHttpServletRequest();
HttpServletRequest transformedRequest = this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
assertThat(requestArg.getValue()).isEqualTo(transformedRequest);
}
/**
* The request passed into the transformer does not allow interactions on certain
* methods, we need to ensure that the methods used by
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)} are overridden.
*/
@Test
void transformThenResultDoesNotDelegateToSetAttribute() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
String attrName = "any";
String attrValue = "value";
transformedRequest.setAttribute(attrName, attrValue);
verifyNoInteractions(request);
assertThat(transformedRequest.getAttribute(attrName)).isEqualTo(attrValue);
}
@Test
void transformThenSetAttributeWorks() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
String attrName = "any";
String attrValue = "value";
transformedRequest.setAttribute(attrName, attrValue);
assertThat(transformedRequest.getAttribute(attrName)).isEqualTo(attrValue);
}
/**
* The request passed into the transformer does not allow interactions on certain
* methods, we need to ensure that the methods used by
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)} are overridden.
*/
@Test
void transformThenResultDoesNotDelegateToGetAttribute() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
transformedRequest.getAttribute("any");
verifyNoInteractions(request);
}
/**
* The request passed into the transformer does not allow interactions on certain
* methods, we need to ensure that the methods used by
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)} are overridden.
*/
@Test
void transformThenResultDoesNotDelegateToGetAttributeNames() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
transformedRequest.getAttributeNames();
verifyNoInteractions(request);
}
@Test
void transformThenGetAttributeNamesWorks() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
String attrName = "any";
String attrValue = "value";
transformedRequest.setAttribute(attrName, attrValue);
assertThat(Collections.list(transformedRequest.getAttributeNames())).containsExactly(attrName);
}
/**
* The request passed into the transformer does not allow interactions on certain
* methods, we need to ensure that the methods used by
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)} are overridden.
*/
@Test
void transformThenResultDoesNotDelegateToRemoveAttribute() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
transformedRequest.removeAttribute("any");
verifyNoInteractions(request);
}
/**
* The request passed into the transformer does not allow interactions on certain
* methods, we need to ensure that the methods used by
* {@link HandlerMappingIntrospector#setCache(HttpServletRequest)} are overridden.
*/
@Test
void transformThenResultDoesNotDelegateToGetDispatcherType() {
HttpServletRequest request = mock(HttpServletRequest.class);
this.transformer.transform(request);
ArgumentCaptor<HttpServletRequest> requestArg = ArgumentCaptor.forClass(HttpServletRequest.class);
verify(this.hmi).setCache(requestArg.capture());
HttpServletRequest transformedRequest = requestArg.getValue();
assertThat(transformedRequest.getDispatcherType()).isEqualTo(DispatcherType.REQUEST);
verifyNoInteractions(request);
}
}