1
0
mirror of synced 2026-07-12 06:10:02 +00:00

Compare commits

...

152 Commits

Author SHA1 Message Date
github-actions[bot] 6adc3b3d99 Release 6.3.1 2024-06-17 15:22:10 +00:00
github-actions[bot] 363159ef53 Merge branch '6.2.x' into 6.3.x 2024-06-17 04:05:02 +00:00
dependabot[bot] 2a6f6ecdb4 Bump org.springframework.data:spring-data-bom from 2023.1.6 to 2023.1.7
Bumps [org.springframework.data:spring-data-bom](https://github.com/spring-projects/spring-data-bom) from 2023.1.6 to 2023.1.7.
- [Release notes](https://github.com/spring-projects/spring-data-bom/releases)
- [Commits](https://github.com/spring-projects/spring-data-bom/compare/2023.1.6...2023.1.7)

---
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>
2024-06-16 21:04:14 -07:00
dependabot[bot] 3ec2a2c309 Bump org.jfrog.buildinfo:build-info-extractor-gradle
Bumps [org.jfrog.buildinfo:build-info-extractor-gradle](https://github.com/jfrog/build-info) from 4.33.17 to 4.33.19.
- [Release notes](https://github.com/jfrog/build-info/releases)
- [Changelog](https://github.com/jfrog/build-info/blob/master/RELEASE.md)
- [Commits](https://github.com/jfrog/build-info/compare/build-info-gradle-extractor-4.33.17...build-info-gradle-extractor-4.33.19)

---
updated-dependencies:
- dependency-name: org.jfrog.buildinfo:build-info-extractor-gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-16 20:45:53 -07:00
dependabot[bot] e5b54ed730 Bump org.springframework.data:spring-data-bom from 2024.0.0 to 2024.0.1
Bumps [org.springframework.data:spring-data-bom](https://github.com/spring-projects/spring-data-bom) from 2024.0.0 to 2024.0.1.
- [Release notes](https://github.com/spring-projects/spring-data-bom/releases)
- [Commits](https://github.com/spring-projects/spring-data-bom/compare/2024.0.0...2024.0.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>
2024-06-16 20:44:54 -07:00
github-actions[bot] 73e2e751a1 Merge branch '5.8.x' into 6.2.x 2024-06-14 04:20:20 +00:00
github-actions[bot] 64b698fc48 Merge branch '6.2.x' into 6.3.x 2024-06-14 04:20:20 +00:00
dependabot[bot] 2537a033f5 Bump org.springframework:spring-framework-bom from 5.3.36 to 5.3.37
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 5.3.36 to 5.3.37.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.36...v5.3.37)

---
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>
2024-06-13 21:19:30 -07:00
dependabot[bot] d4e151c8a4 Bump org.springframework:spring-framework-bom from 6.1.8 to 6.1.9
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.8 to 6.1.9.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.8...v6.1.9)

---
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>
2024-06-13 20:48:17 -07:00
dependabot[bot] 5587fe1015 Bump org.springframework.ldap:spring-ldap-core from 3.2.3 to 3.2.4
Bumps [org.springframework.ldap:spring-ldap-core](https://github.com/spring-projects/spring-ldap) from 3.2.3 to 3.2.4.
- [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.3...3.2.4)

---
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>
2024-06-13 20:43:54 -07:00
github-actions[bot] a0cdf099c0 Merge branch '6.2.x' into 6.3.x 2024-06-14 03:27:28 +00:00
dependabot[bot] 79c8eb3af4 Bump org.springframework:spring-framework-bom from 6.1.8 to 6.1.9
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.8 to 6.1.9.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.8...v6.1.9)

---
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>
2024-06-13 20:26:45 -07:00
github-actions[bot] 996e1be952 Merge branch '6.2.x' into 6.3.x 2024-06-14 03:23:41 +00:00
dependabot[bot] 3d9df377ef Bump org.springframework.ldap:spring-ldap-core from 3.2.3 to 3.2.4
Bumps [org.springframework.ldap:spring-ldap-core](https://github.com/spring-projects/spring-ldap) from 3.2.3 to 3.2.4.
- [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.3...3.2.4)

---
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>
2024-06-13 20:22:50 -07:00
Steve Riesenberg 5c0f1730d6 Merge branch '6.2.x' into 6.3.x
Closes gh-15245
2024-06-13 16:02:51 -05:00
Steve Riesenberg e41771491b Merge branch '5.8.x' into 6.2.x
Closes gh-15244
2024-06-13 16:02:05 -05:00
Steve Riesenberg f622d8e2e2 Polish gh-15235 2024-06-13 16:00:03 -05:00
Harsh4902 92cab2b678 Add 'Required Dependencies' section in ldap.adoc file
Closes gh-14699
2024-06-13 16:00:02 -05:00
github-actions[bot] f47a7123e8 Merge branch '6.2.x' into 6.3.x 2024-06-13 03:54:55 +00:00
dependabot[bot] 0913903110 Bump com.gradle.develocity from 3.17.4 to 3.17.5
Bumps com.gradle.develocity from 3.17.4 to 3.17.5.

---
updated-dependencies:
- dependency-name: com.gradle.develocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-12 20:54:09 -07:00
github-actions[bot] b5187b5da7 Merge branch '6.2.x' into 6.3.x 2024-06-13 03:46:58 +00:00
github-actions[bot] eb0babc5a6 Merge branch '5.8.x' into 6.2.x 2024-06-13 03:46:58 +00:00
dependabot[bot] 254709ce0b Bump com.gradle.develocity from 3.17.4 to 3.17.5
Bumps com.gradle.develocity from 3.17.4 to 3.17.5.

---
updated-dependencies:
- dependency-name: com.gradle.develocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-12 20:46:14 -07:00
dependabot[bot] 5f6b950290 Bump com.gradle.develocity from 3.17.4 to 3.17.5
Bumps com.gradle.develocity from 3.17.4 to 3.17.5.

---
updated-dependencies:
- dependency-name: com.gradle.develocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-12 20:23:16 -07:00
github-actions[bot] a7f8a8a42c Merge branch '5.8.x' into 6.2.x 2024-06-12 04:30:59 +00:00
github-actions[bot] b2c17ec406 Merge branch '6.2.x' into 6.3.x 2024-06-12 04:30:59 +00:00
dependabot[bot] e9c1b7b0ae Bump io.projectreactor:reactor-bom from 2020.0.44 to 2020.0.45
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2020.0.44 to 2020.0.45.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2020.0.44...2020.0.45)

---
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>
2024-06-11 21:30:14 -07:00
github-actions[bot] 329130f244 Merge branch '5.8.x' into 6.2.x 2024-06-12 04:14:02 +00:00
github-actions[bot] 8875094361 Merge branch '6.2.x' into 6.3.x 2024-06-12 04:14:02 +00:00
dependabot[bot] 2b322da9ac Bump io.projectreactor.netty:reactor-netty from 1.0.45 to 1.0.46
Bumps [io.projectreactor.netty:reactor-netty](https://github.com/reactor/reactor-netty) from 1.0.45 to 1.0.46.
- [Release notes](https://github.com/reactor/reactor-netty/releases)
- [Commits](https://github.com/reactor/reactor-netty/compare/v1.0.45...v1.0.46)

---
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>
2024-06-11 21:13:46 -07:00
dependabot[bot] 50235efb75 Bump io.projectreactor:reactor-bom from 2023.0.6 to 2023.0.7
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2023.0.6 to 2023.0.7.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2023.0.6...2023.0.7)

---
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>
2024-06-11 21:13:16 -07:00
dependabot[bot] 4b7499b19b Bump io.projectreactor:reactor-bom from 2023.0.6 to 2023.0.7
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2023.0.6 to 2023.0.7.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2023.0.6...2023.0.7)

---
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>
2024-06-11 21:01:00 -07:00
dependabot[bot] f899641f88 Bump org.hibernate.orm:hibernate-core from 6.4.8.Final to 6.4.9.Final
Bumps [org.hibernate.orm:hibernate-core](https://github.com/hibernate/hibernate-orm) from 6.4.8.Final to 6.4.9.Final.
- [Release notes](https://github.com/hibernate/hibernate-orm/releases)
- [Changelog](https://github.com/hibernate/hibernate-orm/blob/6.4.9/changelog.txt)
- [Commits](https://github.com/hibernate/hibernate-orm/compare/6.4.8...6.4.9)

---
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>
2024-06-11 21:00:08 -07:00
dependabot[bot] 44454c21a4 Bump io.micrometer:micrometer-observation from 1.12.6 to 1.12.7
Bumps [io.micrometer:micrometer-observation](https://github.com/micrometer-metrics/micrometer) from 1.12.6 to 1.12.7.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.12.6...v1.12.7)

---
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>
2024-06-10 21:11:44 -07:00
github-actions[bot] 3df22058bb Merge branch '6.2.x' into 6.3.x 2024-06-11 03:43:06 +00:00
dependabot[bot] ec5cee416e Bump io.micrometer:micrometer-observation from 1.12.6 to 1.12.7
Bumps [io.micrometer:micrometer-observation](https://github.com/micrometer-metrics/micrometer) from 1.12.6 to 1.12.7.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.12.6...v1.12.7)

---
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>
2024-06-10 20:42:20 -07:00
dependabot[bot] 397163b0b2 Bump io-spring-javaformat from 0.0.41 to 0.0.42
Bumps `io-spring-javaformat` from 0.0.41 to 0.0.42.

Updates `io.spring.javaformat:spring-javaformat-checkstyle` from 0.0.41 to 0.0.42
- [Release notes](https://github.com/spring-io/spring-javaformat/releases)
- [Commits](https://github.com/spring-io/spring-javaformat/compare/v0.0.41...v0.0.42)

Updates `io.spring.javaformat:spring-javaformat-gradle-plugin` from 0.0.41 to 0.0.42
- [Release notes](https://github.com/spring-io/spring-javaformat/releases)
- [Commits](https://github.com/spring-io/spring-javaformat/compare/v0.0.41...v0.0.42)

---
updated-dependencies:
- dependency-name: io.spring.javaformat:spring-javaformat-checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.spring.javaformat:spring-javaformat-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 21:18:46 -07:00
dependabot[bot] b7c14608e1 Bump org.jfrog.buildinfo:build-info-extractor-gradle
Bumps [org.jfrog.buildinfo:build-info-extractor-gradle](https://github.com/jfrog/build-info) from 4.33.16 to 4.33.17.
- [Release notes](https://github.com/jfrog/build-info/releases)
- [Changelog](https://github.com/jfrog/build-info/blob/master/RELEASE.md)
- [Commits](https://github.com/jfrog/build-info/compare/build-info-gradle-extractor-4.33.16...build-info-gradle-extractor-4.33.17)

---
updated-dependencies:
- dependency-name: org.jfrog.buildinfo:build-info-extractor-gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 21:16:43 -07:00
github-actions[bot] ff83e3758f Merge branch '6.2.x' into 6.3.x 2024-06-10 03:51:03 +00:00
dependabot[bot] 122b47e6f9 Bump io-spring-javaformat from 0.0.41 to 0.0.42
Bumps `io-spring-javaformat` from 0.0.41 to 0.0.42.

Updates `io.spring.javaformat:spring-javaformat-checkstyle` from 0.0.41 to 0.0.42
- [Release notes](https://github.com/spring-io/spring-javaformat/releases)
- [Commits](https://github.com/spring-io/spring-javaformat/compare/v0.0.41...v0.0.42)

Updates `io.spring.javaformat:spring-javaformat-gradle-plugin` from 0.0.41 to 0.0.42
- [Release notes](https://github.com/spring-io/spring-javaformat/releases)
- [Commits](https://github.com/spring-io/spring-javaformat/compare/v0.0.41...v0.0.42)

---
updated-dependencies:
- dependency-name: io.spring.javaformat:spring-javaformat-checkstyle
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: io.spring.javaformat:spring-javaformat-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 20:50:17 -07:00
Josh Cummings c3f766f3b3 Update RoleHierarchy Documentation
Closes gh-15208
2024-06-06 17:25:28 -06:00
Josh Cummings bce8035bb6 Merge branch '6.2.x' into 6.3.x
Closes gh-15212
2024-06-06 13:45:56 -06:00
Josh Cummings 0532659245 Fix Typo in Oidc Logout Docs
Closes gh-15198
2024-06-06 13:45:35 -06:00
Josh Cummings 22c7b8760a Merge branch '6.2.x' into 6.3.x
Closes gh-15211
2024-06-06 13:36:20 -06:00
Josh Cummings f231ea277d Merge branch '5.8.x' into 6.2.x
Closes gh-15210
2024-06-06 13:35:56 -06:00
Josh Cummings 6aabd768a8 Pick MvcRequestMatcher for MockMvc requests
Closes gh-13849
2024-06-06 13:17:43 -06:00
Marcus Hert Da Coregio 91cd2cec2b Use samplesBranch=6.3.x 2024-06-05 14:16:28 -03:00
Marcus Hert Da Coregio e013d96758 Clarify the behavior of Concurrent Session Management when an IdP is involved
Closes gh-15071
2024-06-05 13:59:24 -03:00
Josh Cummings 0aed8df549 Merge branch '6.2.x' into 6.3.x
Closes gh-15197
2024-06-03 17:42:58 -06:00
Josh Cummings d6228e0882 Merge branch '5.8.x' into 6.2.x
Closes gh-15196
2024-06-03 17:42:25 -06:00
Josh Cummings cdd626644e Use Request-Level Servlet Context
Spring Security cannot use the ServletContext attached
to the ApplicationContext since there may be child
ApplicationContext's with their own ServletContext.

Because of that, it is necessary to always use the
ServletContext attached to the request.

Closes gh-14418
2024-06-03 17:41:51 -06:00
Josh Cummings 5a798e93f1 Polish MVC Tests
Issue gh-14418
2024-06-03 17:41:51 -06:00
dependabot[bot] 693cee9f3e Bump org.hsqldb:hsqldb from 2.7.2 to 2.7.3
Bumps org.hsqldb:hsqldb from 2.7.2 to 2.7.3.

---
updated-dependencies:
- dependency-name: org.hsqldb:hsqldb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-02 20:55:00 -07:00
github-actions[bot] 4330bda97e Merge branch '6.2.x' into 6.3.x 2024-06-03 03:51:08 +00:00
dependabot[bot] 8743186423 Bump org.hsqldb:hsqldb from 2.7.2 to 2.7.3
Bumps org.hsqldb:hsqldb from 2.7.2 to 2.7.3.

---
updated-dependencies:
- dependency-name: org.hsqldb:hsqldb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-02 20:50:24 -07:00
github-actions[bot] ebb44d704f Merge branch '6.2.x' into 6.3.x 2024-06-03 03:35:22 +00:00
github-actions[bot] 2dd1c58450 Merge branch '5.8.x' into 6.2.x 2024-06-03 03:35:21 +00:00
dependabot[bot] aa88404d69 Bump org.hsqldb:hsqldb from 2.7.2 to 2.7.3
Bumps org.hsqldb:hsqldb from 2.7.2 to 2.7.3.

---
updated-dependencies:
- dependency-name: org.hsqldb:hsqldb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-02 20:34:36 -07:00
Steve Riesenberg 1e4aff2bdb Merge branch '6.2.x' into 6.3.x
Closes gh-15186
2024-05-31 19:02:31 -05:00
Steve Riesenberg 3fc7b6e921 Merge branch '5.8.x' into 6.2.x
Closes gh-15185
2024-05-31 18:34:14 -05:00
Steve Riesenberg dcb8c563e8 Fix ArrayIndexOutOfBoundsException
Issue gh-13310
Closes gh-15184
2024-05-31 18:12:21 -05:00
Josh Cummings 3defed4c3d Merge branch '6.2.x' into 6.3.x 2024-05-31 14:13:46 -06:00
Josh Cummings 1cc66faaef Polish Update Signature Validator
Issue gh-15022
2024-05-31 14:13:23 -06:00
Josh Cummings 0da7284ddd Merge branch '6.2.x' into 6.3.x
Closes gh-15183
2024-05-31 13:46:32 -06:00
Josh Cummings 99f233f98c Update Signature Validator
Closes gh-15022
2024-05-31 13:29:28 -06:00
Josh Cummings 7288fecc24 Verify ipAddress Not A Hostname
Closes gh-15172
2024-05-30 17:50:56 -06:00
Steve Riesenberg db9f5935ae Merge branch '6.2.x' into 6.3.x 2024-05-29 16:24:05 -05:00
Steve Riesenberg 5a1d261ce0 Merge branch '5.8.x' into 6.2.x 2024-05-29 16:23:37 -05:00
Steve Riesenberg e34621ec2c Polish gh-14977 2024-05-29 16:23:00 -05:00
JANG 1695d03b72 Assert WebSession is not null
Issue gh-14975
2024-05-29 14:55:37 -05:00
Josh Cummings dd5edeb255 Preserve ArrayListFromString Type
Closes gh-15165
2024-05-28 12:43:57 -06:00
dependabot[bot] d067aca43d Bump org.jfrog.buildinfo:build-info-extractor-gradle
Bumps [org.jfrog.buildinfo:build-info-extractor-gradle](https://github.com/jfrog/build-info) from 4.33.15 to 4.33.16.
- [Release notes](https://github.com/jfrog/build-info/releases)
- [Changelog](https://github.com/jfrog/build-info/blob/master/RELEASE.md)
- [Commits](https://github.com/jfrog/build-info/compare/build-info-gradle-extractor-4.33.15...build-info-gradle-extractor-4.33.16)

---
updated-dependencies:
- dependency-name: org.jfrog.buildinfo:build-info-extractor-gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 20:55:34 -07:00
github-actions[bot] 28c8432676 Merge branch '6.2.x' into 6.3.x 2024-05-27 04:10:08 +00:00
dependabot[bot] 130e7d1b3f Bump org.apache.maven:maven-resolver-provider from 3.9.6 to 3.9.7
Bumps [org.apache.maven:maven-resolver-provider](https://github.com/apache/maven) from 3.9.6 to 3.9.7.
- [Release notes](https://github.com/apache/maven/releases)
- [Commits](https://github.com/apache/maven/compare/maven-3.9.6...maven-3.9.7)

---
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>
2024-05-26 21:09:20 -07:00
dependabot[bot] 737c50c323 Bump org.apache.maven:maven-resolver-provider from 3.9.6 to 3.9.7
Bumps [org.apache.maven:maven-resolver-provider](https://github.com/apache/maven) from 3.9.6 to 3.9.7.
- [Release notes](https://github.com/apache/maven/releases)
- [Commits](https://github.com/apache/maven/compare/maven-3.9.6...maven-3.9.7)

---
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>
2024-05-26 20:33:39 -07:00
Josh Cummings 1c6726d20a Merge branch '6.2.x' into 6.3.x
Closes gh-15167
2024-05-24 15:06:34 -06:00
Josh Cummings 797550fee7 Merge branch '5.8.x' into 6.2.x
Closes gh-15166
2024-05-24 15:04:04 -06:00
Josh Cummings e7ea4091a0 Migrate SampleLDIF to UnboundID
Closes gh-15089
2024-05-24 15:03:53 -06:00
Josh Cummings 659801163e Merge branch '6.2.x' into 6.3.x 2024-05-24 14:26:43 -06:00
Josh Cummings d0f95c90c5 Merge branch '5.8.x' into 6.2.x 2024-05-24 14:25:23 -06:00
dependabot[bot] 235dfc4dfd Bump @antora/collector-extension in /docs
---
updated-dependencies:
- dependency-name: "@antora/collector-extension"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-24 07:57:40 -07:00
github-actions[bot] f820ef19a4 Merge branch '6.2.x' into 6.3.x 2024-05-24 14:45:22 +00:00
dependabot[bot] a30088fc0a Bump @antora/collector-extension in /docs
---
updated-dependencies:
- dependency-name: "@antora/collector-extension"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-24 07:44:23 -07:00
dependabot[bot] a9419bb69c Bump @antora/collector-extension in /docs
---
updated-dependencies:
- dependency-name: "@antora/collector-extension"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-24 07:43:51 -07:00
dependabot[bot] 7f56306dcc Bump gradle/gradle-build-action from 2 to 3
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2 to 3.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](https://github.com/gradle/gradle-build-action/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-24 07:43:21 -07:00
Marcus Hert Da Coregio ddcaeb5c20 Serialize objects from 6.3.x
Issue gh-3737
2024-05-24 09:47:29 -03:00
Marcus Hert Da Coregio 2c7b7a5e42 Move update-antora-ui-spring.yml to docs-build
So we don't have duplicate workflows between maintenance branches

Issue gh-15106
2024-05-24 09:35:59 -03:00
Josh Cummings 092a63d1e0 Conditionally Add Conventions Plugin 2024-05-23 16:56:35 -06:00
Josh Cummings 6956ed693c Polish DefaultSecurityFilterChain Logs
Reuse String manipulation logic in Spring Framework
Compress whitespace

Closes gh-15096
2024-05-23 12:20:14 -06:00
baezzys ac9bdf5cbf Change DefaultSecurityFilterChain logging to DEBUG level and simplify filter log
- Change DefaultSecurityFilterChain logging level from INFO to DEBUG to align with FilterChainProxy.
- Log filter class names instead of the toString() of filter.
2024-05-23 12:02:35 -06:00
Marcus Hert Da Coregio da1869c271 Merge branch '6.2.x'
Closes gh-15151
2024-05-23 14:17:20 -03:00
Marcus Hert Da Coregio 58cbc47376 Merge branch '5.8.x' into 6.2.x
Closes gh-15150
2024-05-23 14:17:09 -03:00
Caio Henrique 896dd93313 fix: add correction to java example in multitenancy.adoc
Closes gh-15146
2024-05-23 14:16:59 -03:00
Marcus Hert Da Coregio 0acf6cca6e Merge branch '6.2.x'
Closes gh-15149
2024-05-23 14:05:06 -03:00
Marcus Hert Da Coregio 47ad405063 Merge branch '5.8.x' into 6.2.x
Closes gh-15148
2024-05-23 14:04:35 -03:00
Marcus Hert Da Coregio c7b739eb3f Fix broken link to jaspan article
Closes gh-14358
2024-05-23 14:04:10 -03:00
Alexander Münch df59516b18 Fix Kotlin example in authorize-http-requests.adoc
- Consistency: Replaced mix of tabs/spaces with spaces indentation
2024-05-23 13:57:32 -03:00
Marcus Hert Da Coregio 9744cc44d2 Merge branch '6.2.x'
Closes gh-15144
2024-05-23 08:17:26 -03:00
douxf bd72741879 Fix wrong class on documentation
Closes gh-15045
2024-05-23 08:15:56 -03:00
github-actions[bot] 97f8c4b80e Merge branch '6.2.x' 2024-05-23 11:11:07 +00:00
github-actions[bot] 08d8f56cd6 Merge branch '5.8.x' into 6.2.x 2024-05-23 11:11:07 +00:00
dependabot[bot] 32e860523c Bump @springio/antora-extensions from 1.10.0 to 1.11.1 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.10.0 to 1.11.1.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.10.0...v1.11.1)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-23 04:10:21 -07:00
github-actions[bot] 57f7b42345 Merge branch '6.2.x' 2024-05-23 11:03:37 +00:00
dependabot[bot] cda45d6f2c Bump @springio/antora-extensions from 1.10.0 to 1.11.1 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.10.0 to 1.11.1.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.10.0...v1.11.1)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-23 04:02:50 -07:00
dependabot[bot] 6c70b8740e Bump @springio/antora-extensions from 1.10.0 to 1.11.1 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.10.0 to 1.11.1.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.10.0...v1.11.1)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-23 04:02:47 -07:00
dependabot[bot] 0364d1e21f Bump spring-io/spring-doc-actions
Bumps [spring-io/spring-doc-actions](https://github.com/spring-io/spring-doc-actions) from 17ed79ea5fbd65813c69ef1062a024d4a37ff0ca to 5a57bcc6a0da2a1474136cf29571b277850432bc.
- [Commits](https://github.com/spring-io/spring-doc-actions/compare/17ed79ea5fbd65813c69ef1062a024d4a37ff0ca...5a57bcc6a0da2a1474136cf29571b277850432bc)

---
updated-dependencies:
- dependency-name: spring-io/spring-doc-actions
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-23 04:02:32 -07:00
Marcus Hert Da Coregio 6818480d7a Remove 6.1.x from Dependabot 2024-05-23 08:02:06 -03:00
Marcus Hert Da Coregio dc27ae59ad Configure Dependabot to update docs/package.json
Closes gh-15128
2024-05-23 07:58:50 -03:00
github-actions[bot] 80737c1a39 Merge branch '5.8.x' into 6.2.x 2024-05-23 04:10:07 +00:00
github-actions[bot] 09fac2265c Merge branch '6.2.x' 2024-05-23 04:10:07 +00:00
dependabot[bot] 58232b1172 Bump org.springframework:spring-framework-bom from 5.3.35 to 5.3.36
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 5.3.35 to 5.3.36.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.35...v5.3.36)

---
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>
2024-05-22 21:09:25 -07:00
dependabot[bot] ade8a5e5a4 Bump org.springframework:spring-framework-bom from 6.1.7 to 6.1.8
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.7 to 6.1.8.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.7...v6.1.8)

---
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>
2024-05-22 21:04:47 -07:00
dependabot[bot] f51b35cbdc Bump org.gretty:gretty from 4.1.3 to 4.1.4
Bumps [org.gretty:gretty](https://github.com/gretty-gradle-plugin/gretty) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/gretty-gradle-plugin/gretty/releases)
- [Changelog](https://github.com/gretty-gradle-plugin/gretty/blob/master/changes.md)
- [Commits](https://github.com/gretty-gradle-plugin/gretty/compare/v4.1.3...v4.1.4)

---
updated-dependencies:
- dependency-name: org.gretty:gretty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-22 21:00:14 -07:00
github-actions[bot] 9ee0a52316 Merge branch '6.2.x' 2024-05-23 03:54:42 +00:00
dependabot[bot] 395310deb6 Bump org.springframework:spring-framework-bom from 6.1.7 to 6.1.8
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.1.7 to 6.1.8.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.7...v6.1.8)

---
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>
2024-05-22 20:53:56 -07:00
github-actions[bot] 7b5914ddf8 Merge branch '6.2.x' 2024-05-21 17:39:12 +00:00
github-actions[bot] 2ff8dfe239 Merge branch '5.8.x' into 6.2.x 2024-05-21 17:39:12 +00:00
dependabot[bot] 0e8fd1cd6c Bump com.github.spullara.mustache.java:compiler from 0.9.11 to 0.9.13
Bumps [com.github.spullara.mustache.java:compiler](https://github.com/spullara/mustache.java) from 0.9.11 to 0.9.13.
- [Commits](https://github.com/spullara/mustache.java/compare/mustache.java-0.9.11...mustache.java-0.9.13)

---
updated-dependencies:
- dependency-name: com.github.spullara.mustache.java:compiler
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-21 10:38:07 -07:00
Marcus Hert Da Coregio d1cd51ebd2 Allow updates from spring-io and spring-security-release-tools
Closes gh-15124
2024-05-21 14:24:51 -03:00
github-actions[bot] 3d7bcd2fad Merge branch '5.8.x' into 6.2.x 2024-05-21 15:37:45 +00:00
github-actions[bot] 324415a4a0 Merge branch '6.2.x' 2024-05-21 15:37:45 +00:00
dependabot[bot] 1f001f8a6d Bump com.gradle.develocity from 3.17.2 to 3.17.4
Bumps com.gradle.develocity from 3.17.2 to 3.17.4.

---
updated-dependencies:
- dependency-name: com.gradle.develocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-21 08:36:59 -07:00
github-actions[bot] ca40d90d2c Merge branch '5.8.x' into 6.2.x 2024-05-21 01:06:14 +00:00
github-actions[bot] dcef7ef454 Merge branch '6.2.x' 2024-05-21 01:06:14 +00:00
dependabot[bot] 3fdfa98172 Bump org.springframework:spring-framework-bom from 5.3.34 to 5.3.35
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 5.3.34 to 5.3.35.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.34...v5.3.35)

---
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>
2024-05-20 18:05:26 -07:00
github-actions[bot] c6009ae007 Merge branch '5.8.x' into 6.2.x 2024-05-20 22:49:19 +00:00
github-actions[bot] 1373bee220 Merge branch '6.2.x' 2024-05-20 22:49:19 +00:00
dependabot[bot] 90f5141880 Bump io.projectreactor.netty:reactor-netty from 1.0.44 to 1.0.45
Bumps [io.projectreactor.netty:reactor-netty](https://github.com/reactor/reactor-netty) from 1.0.44 to 1.0.45.
- [Release notes](https://github.com/reactor/reactor-netty/releases)
- [Commits](https://github.com/reactor/reactor-netty/compare/v1.0.44...v1.0.45)

---
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>
2024-05-20 15:48:30 -07:00
github-actions[bot] a57ba8a8d0 Merge branch '5.8.x' into 6.2.x 2024-05-20 22:36:48 +00:00
github-actions[bot] 8cb2d17eb1 Merge branch '6.2.x' 2024-05-20 22:36:48 +00:00
dependabot[bot] ab6667eb5c Bump io.projectreactor:reactor-bom from 2020.0.43 to 2020.0.44
Bumps [io.projectreactor:reactor-bom](https://github.com/reactor/reactor) from 2020.0.43 to 2020.0.44.
- [Release notes](https://github.com/reactor/reactor/releases)
- [Commits](https://github.com/reactor/reactor/compare/2020.0.43...2020.0.44)

---
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>
2024-05-20 15:35:59 -07:00
Josh Cummings 8357b149fd Merge branch '6.2.x' 2024-05-20 16:21:24 -06:00
Josh Cummings 013c46098e Merge branch '6.1.x' into 6.2.x 2024-05-20 16:21:15 -06:00
Josh Cummings 5bfd1f59d1 Merge branch '5.8.x' into 6.1.x 2024-05-20 16:21:04 -06:00
Josh Cummings 4b10c2daac Turn Off Build Scans
Currently, --scan is preventing PR builds from completing.

Issue gh-15120
2024-05-20 16:20:43 -06:00
Josh Cummings 720b43924a Merge branch '6.2.x' 2024-05-20 12:43:58 -06:00
Josh Cummings 491f494991 Merge branch '6.1.x' into 6.2.x 2024-05-20 12:43:41 -06:00
Josh Cummings 0e4d29763f Merge branch '5.8.x' into 6.1.x 2024-05-20 12:42:52 -06:00
Josh Cummings 63e24a3026 Adjust JavaDoc Classpath
Issue gh-14931
2024-05-20 12:42:01 -06:00
Marcus Hert Da Coregio f115f90151 Merge branch '6.2.x' 2024-05-20 13:52:18 -03:00
Marcus Hert Da Coregio 7251c7ffb7 Merge branch '6.1.x' into 6.2.x 2024-05-20 13:52:07 -03:00
Marcus Hert Da Coregio 514600721c Merge branch '5.8.x' into 6.1.x 2024-05-20 13:51:57 -03:00
github-actions[bot] 2e4ea1eec5 Update Antora Spring UI to v0.4.15 2024-05-20 13:51:40 -03:00
github-actions[bot] 86de2dbf6f Update Antora Spring UI to v0.4.15 2024-05-20 13:51:35 -03:00
github-actions[bot] 2563b854ea Update Antora Spring UI to v0.4.15 2024-05-20 13:51:29 -03:00
github-actions[bot] 9027dceb71 Update Antora Spring UI to v0.4.15 2024-05-20 13:51:18 -03:00
Marcus Hert Da Coregio 984939b5f7 Move docs-build update to new job to avoid concurrency issues with matrix strategy
Issue gh-15106
2024-05-20 13:41:27 -03:00
github-actions[bot] 3582673cac Next development version 2024-05-20 16:38:09 +00:00
dependabot[bot] d61a85f74b Bump com.gradle.develocity from 3.17.3 to 3.17.4
Bumps com.gradle.develocity from 3.17.3 to 3.17.4.

---
updated-dependencies:
- dependency-name: com.gradle.develocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-19 20:39:20 -07:00
dependabot[bot] 8b3d33ed64 Bump org.springframework:spring-framework-bom from 6.0.19 to 6.0.20
Bumps [org.springframework:spring-framework-bom](https://github.com/spring-projects/spring-framework) from 6.0.19 to 6.0.20.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.0.19...v6.0.20)

---
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>
2024-05-16 20:31:22 -07:00
dependabot[bot] defe27d53e Bump io.mockk:mockk from 1.13.10 to 1.13.11
Bumps [io.mockk:mockk](https://github.com/mockk/mockk) from 1.13.10 to 1.13.11.
- [Release notes](https://github.com/mockk/mockk/releases)
- [Commits](https://github.com/mockk/mockk/compare/1.13.10...1.13.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-16 20:31:02 -07:00
dependabot[bot] c5b86370ff Bump org-eclipse-jetty from 11.0.20 to 11.0.21
Bumps `org-eclipse-jetty` from 11.0.20 to 11.0.21.

Updates `org.eclipse.jetty:jetty-server` from 11.0.20 to 11.0.21

Updates `org.eclipse.jetty:jetty-servlet` from 11.0.20 to 11.0.21

---
updated-dependencies:
- dependency-name: org.eclipse.jetty:jetty-server
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.eclipse.jetty:jetty-servlet
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-16 20:29:46 -07:00
90 changed files with 633 additions and 281 deletions
+16 -55
View File
@@ -29,31 +29,6 @@ updates:
update-types:
- version-update:semver-major
- version-update:semver-minor
- package-ecosystem: gradle
target-branch: 6.1.x
directory: /
schedule:
interval: daily
time: '03:00'
timezone: Etc/UTC
labels:
- 'type: dependency-upgrade'
registries:
- spring-milestones
ignore:
- dependency-name: com.nimbusds:nimbus-jose-jwt
- dependency-name: org.python:jython
- dependency-name: org.apache.directory.server:*
- 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: 6.2.x
directory: /
@@ -118,32 +93,6 @@ updates:
- 'in: build'
ignore:
- dependency-name: sjohnr/*
- dependency-name: spring-io/*
- dependency-name: spring-security-release-tools/*
- package-ecosystem: github-actions
target-branch: 6.1.x
directory: /
schedule:
interval: weekly
labels:
- 'type: task'
- 'in: build'
ignore:
- dependency-name: sjohnr/*
- dependency-name: spring-io/*
- dependency-name: spring-security-release-tools/*
- package-ecosystem: github-actions
target-branch: 6.2.x
directory: /
schedule:
interval: weekly
labels:
- 'type: task'
- 'in: build'
ignore:
- dependency-name: sjohnr/*
- dependency-name: spring-io/*
- dependency-name: spring-security-release-tools/*
- package-ecosystem: github-actions
target-branch: main
directory: /
@@ -154,8 +103,6 @@ updates:
- 'in: build'
ignore:
- dependency-name: sjohnr/*
- dependency-name: spring-io/*
- dependency-name: spring-security-release-tools/*
- package-ecosystem: github-actions
target-branch: docs-build
directory: /
@@ -166,11 +113,25 @@ updates:
- 'in: build'
ignore:
- dependency-name: sjohnr/*
- dependency-name: spring-io/*
- dependency-name: spring-security-release-tools/*
- package-ecosystem: npm
target-branch: docs-build
directory: /
schedule:
interval: weekly
- package-ecosystem: npm
target-branch: main
directory: /docs
schedule:
interval: weekly
- package-ecosystem: npm
target-branch: 6.2.x
directory: /docs
schedule:
interval: weekly
- package-ecosystem: npm
target-branch: 5.8.x
directory: /docs
schedule:
interval: weekly
@@ -25,7 +25,7 @@ jobs:
java-version: '17'
distribution: 'temurin'
- name: Set up Gradle
uses: gradle/gradle-build-action@v2
uses: gradle/gradle-build-action@v3
- name: Upgrade Wrappers
run: ./gradlew clean upgradeGradleWrapperAll --continue -Porg.gradle.java.installations.auto-download=false
env:
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew clean build --continue --scan
run: ./gradlew clean build --continue
generate-docs:
name: Generate Docs
runs-on: ubuntu-latest
@@ -1,29 +0,0 @@
name: Update Antora UI Spring
on:
workflow_dispatch:
permissions:
pull-requests: write
issues: write
contents: write
jobs:
update-antora-ui-spring:
runs-on: ubuntu-latest
name: Update
strategy:
matrix:
branch: [ '5.8.x', '6.1.x', '6.2.x', 'main' ]
steps:
- uses: spring-io/spring-doc-actions/update-antora-spring-ui@17ed79ea5fbd65813c69ef1062a024d4a37ff0ca
name: Update on Supported Branches
with:
docs-branch: ${{ matrix.branch }}
token: ${{ secrets.GITHUB_TOKEN }}
antora-file-path: 'docs/antora-playbook.yml'
- uses: spring-io/spring-doc-actions/update-antora-spring-ui@17ed79ea5fbd65813c69ef1062a024d4a37ff0ca
name: Update on docs-build
with:
docs-branch: 'docs-build'
token: ${{ secrets.GITHUB_TOKEN }}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@@ -42,11 +43,13 @@ import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
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.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
/**
@@ -203,43 +206,22 @@ public abstract class AbstractRequestMatcherRegistry<C> {
if (servletContext == null) {
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
}
boolean isProgrammaticApiAvailable = isProgrammaticApiAvailable(servletContext);
List<RequestMatcher> matchers = new ArrayList<>();
for (String pattern : patterns) {
AntPathRequestMatcher ant = new AntPathRequestMatcher(pattern, (method != null) ? method.name() : null);
MvcRequestMatcher mvc = createMvcMatchers(method, pattern).get(0);
if (isProgrammaticApiAvailable) {
matchers.add(resolve(ant, mvc, servletContext));
}
else {
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));
}
matchers.add(new DeferredRequestMatcher((c) -> resolve(ant, mvc, c), mvc, ant));
}
return requestMatchers(matchers.toArray(new RequestMatcher[0]));
}
private static boolean isProgrammaticApiAvailable(ServletContext servletContext) {
try {
servletContext.getServletRegistrations();
return true;
}
catch (UnsupportedOperationException ex) {
return false;
}
}
private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) {
Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext);
if (registrations.isEmpty()) {
return ant;
return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher());
}
if (!hasDispatcherServlet(registrations)) {
return ant;
return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher());
}
ServletRegistration dispatcherServlet = requireOneRootDispatcherServlet(registrations);
if (dispatcherServlet != null) {
@@ -474,34 +456,29 @@ public abstract class AbstractRequestMatcherRegistry<C> {
static class DeferredRequestMatcher implements RequestMatcher {
final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory;
final Function<ServletContext, RequestMatcher> requestMatcherFactory;
final AtomicReference<String> description = new AtomicReference<>();
volatile RequestMatcher requestMatcher;
final Map<ServletContext, RequestMatcher> requestMatchers = new ConcurrentHashMap<>();
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;
};
DeferredRequestMatcher(Function<ServletContext, RequestMatcher> resolver, RequestMatcher... candidates) {
this.requestMatcherFactory = (sc) -> this.requestMatchers.computeIfAbsent(sc, resolver);
this.description.set("Deferred " + Arrays.toString(candidates));
}
RequestMatcher requestMatcher(ServletContext servletContext) {
return this.requestMatcherFactory.apply(servletContext);
}
@Override
public boolean matches(HttpServletRequest request) {
return this.requestMatcherFactory.apply(request).matches(request);
return this.requestMatcherFactory.apply(request.getServletContext()).matches(request);
}
@Override
public MatchResult matcher(HttpServletRequest request) {
return this.requestMatcherFactory.apply(request).matcher(request);
return this.requestMatcherFactory.apply(request.getServletContext()).matcher(request);
}
@Override
@@ -511,27 +488,70 @@ public abstract class AbstractRequestMatcherRegistry<C> {
}
static class MockMvcRequestMatcher implements RequestMatcher {
@Override
public boolean matches(HttpServletRequest request) {
return request.getAttribute("org.springframework.test.web.servlet.MockMvc.MVC_RESULT_ATTRIBUTE") != null;
}
}
static class DispatcherServletRequestMatcher implements RequestMatcher {
private final ServletContext servletContext;
DispatcherServletRequestMatcher(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
public boolean matches(HttpServletRequest request) {
String name = request.getHttpServletMapping().getServletName();
ServletRegistration registration = this.servletContext.getServletRegistration(name);
Assert.notNull(name, "Failed to find servlet [" + name + "] in the servlet context");
try {
Class<?> clazz = Class.forName(registration.getClassName());
return DispatcherServlet.class.isAssignableFrom(clazz);
}
catch (ClassNotFoundException ex) {
return false;
}
}
}
static class DispatcherServletDelegatingRequestMatcher implements RequestMatcher {
private final AntPathRequestMatcher ant;
private final MvcRequestMatcher mvc;
private final ServletContext servletContext;
private final RequestMatcher dispatcherServlet;
DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc,
ServletContext servletContext) {
this(ant, mvc, new OrRequestMatcher(new MockMvcRequestMatcher(),
new DispatcherServletRequestMatcher(servletContext)));
}
DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc,
RequestMatcher dispatcherServlet) {
this.ant = ant;
this.mvc = mvc;
this.servletContext = servletContext;
this.dispatcherServlet = dispatcherServlet;
}
RequestMatcher requestMatcher(HttpServletRequest request) {
if (this.dispatcherServlet.matches(request)) {
return this.mvc;
}
return this.ant;
}
@Override
public boolean matches(HttpServletRequest request) {
String name = request.getHttpServletMapping().getServletName();
ServletRegistration registration = this.servletContext.getServletRegistration(name);
Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context");
if (isDispatcherServlet(registration)) {
if (this.dispatcherServlet.matches(request)) {
return this.mvc.matches(request);
}
return this.ant.matches(request);
@@ -539,27 +559,12 @@ public abstract class AbstractRequestMatcherRegistry<C> {
@Override
public MatchResult matcher(HttpServletRequest request) {
String name = request.getHttpServletMapping().getServletName();
ServletRegistration registration = this.servletContext.getServletRegistration(name);
Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context");
if (isDispatcherServlet(registration)) {
if (this.dispatcherServlet.matches(request)) {
return this.mvc.matcher(request);
}
return this.ant.matcher(request);
}
private boolean isDispatcherServlet(ServletRegistration registration) {
Class<?> dispatcherServlet = ClassUtils
.resolveClassName("org.springframework.web.servlet.DispatcherServlet", null);
try {
Class<?> clazz = Class.forName(registration.getClassName());
return dispatcherServlet.isAssignableFrom(clazz);
}
catch (ClassNotFoundException ex) {
return false;
}
}
@Override
public String toString() {
return "DispatcherServletDelegating [" + "ant = " + this.ant + ", mvc = " + this.mvc + "]";
@@ -29,6 +29,7 @@ import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -59,6 +60,7 @@ import org.springframework.security.cas.authentication.CasAssertionAuthenticatio
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.security.cas.authentication.CasServiceTicketAuthenticationToken;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.session.ReactiveSessionInformation;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
@@ -138,6 +140,8 @@ class SpringSecurityCoreVersionSerializableTests {
generatorByClassName.put(OidcUserInfo.class, (r) -> OidcUserInfo.builder().email("email@example.com").build());
generatorByClassName.put(SessionInformation.class,
(r) -> new SessionInformation(user, r.alphanumeric(4), new Date(1704378933936L)));
generatorByClassName.put(ReactiveSessionInformation.class,
(r) -> new ReactiveSessionInformation(user, r.alphanumeric(4), Instant.ofEpochMilli(1704378933936L)));
generatorByClassName.put(OAuth2LoginAuthenticationToken.class, (r) -> {
var token = new OAuth2LoginAuthenticationToken(clientRegistration,
TestOAuth2AuthorizationExchanges.success());
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -26,27 +26,35 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.config.MockServletContext;
import org.springframework.security.config.TestMockHttpServletMappings;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.DispatcherServletDelegatingRequestMatcher;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
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.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.InstanceOfAssertFactories.type;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
* Tests for {@link AbstractRequestMatcherRegistry}.
@@ -167,18 +175,65 @@ public class AbstractRequestMatcherRegistryTests {
mockMvcIntrospector(true);
MockServletContext servletContext = new MockServletContext();
given(this.context.getServletContext()).willReturn(servletContext);
servletContext.addServlet("servletOne", Servlet.class).addMapping("/one");
servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two");
MockHttpServletRequest request = new MockHttpServletRequest();
List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(AntPathRequestMatcher.class);
servletContext.addServlet("servletOne", Servlet.class).addMapping("/one");
servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two");
requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(AntPathRequestMatcher.class);
servletContext.addServlet("servletOne", Servlet.class);
servletContext.addServlet("servletTwo", Servlet.class);
requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(AntPathRequestMatcher.class);
}
// gh-14418
@Test
public void requestMatchersWhenNoDispatcherServletMockMvcThenMvcRequestMatcherType() throws Exception {
MockServletContext servletContext = new MockServletContext();
try (SpringTestContext spring = new SpringTestContext(this)) {
spring.register(MockMvcConfiguration.class)
.postProcessor((context) -> context.setServletContext(servletContext))
.autowire();
this.matcherRegistry.setApplicationContext(spring.getContext());
MockMvc mvc = MockMvcBuilders.webAppContextSetup(spring.getContext()).build();
MockHttpServletRequest request = mvc.perform(get("/")).andReturn().getRequest();
List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(MvcRequestMatcher.class);
servletContext.addServlet("servletOne", Servlet.class).addMapping("/one");
servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two");
requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(MvcRequestMatcher.class);
servletContext.addServlet("servletOne", Servlet.class);
servletContext.addServlet("servletTwo", Servlet.class);
requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).isNotEmpty();
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class))
.extracting((matcher) -> matcher.requestMatcher(request))
.isInstanceOf(MvcRequestMatcher.class);
}
}
@Test
@@ -303,11 +358,13 @@ public class AbstractRequestMatcherRegistryTests {
return requestMatchers;
}
private static List<RequestMatcher> unwrap(List<RequestMatcher> wrappedMatchers) {
private List<RequestMatcher> unwrap(List<RequestMatcher> wrappedMatchers) {
List<RequestMatcher> requestMatchers = new ArrayList<>();
for (RequestMatcher requestMatcher : wrappedMatchers) {
if (requestMatcher instanceof AbstractRequestMatcherRegistry.DeferredRequestMatcher) {
requestMatchers.add(((DeferredRequestMatcher) requestMatcher).requestMatcher);
if (requestMatcher instanceof DeferredRequestMatcher) {
DeferredRequestMatcher deferred = (DeferredRequestMatcher) requestMatcher;
WebApplicationContext web = (WebApplicationContext) getApplicationContext();
requestMatchers.add(deferred.requestMatcher(web.getServletContext()));
}
else {
requestMatchers.add(requestMatcher);
@@ -318,4 +375,11 @@ public class AbstractRequestMatcherRegistryTests {
}
@Configuration
@EnableWebSecurity
@EnableWebMvc
static class MockMvcConfiguration {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -78,7 +78,7 @@ public class AuthorizeRequestsTests {
@BeforeEach
public void setup() {
this.servletContext = spy(MockServletContext.mvc());
this.request = new MockHttpServletRequest("GET", "");
this.request = new MockHttpServletRequest(this.servletContext, "GET", "");
this.request.setMethod("GET");
this.response = new MockHttpServletResponse();
this.chain = new MockFilterChain();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -75,7 +75,7 @@ public class HttpSecuritySecurityMatchersTests {
@BeforeEach
public void setup() throws Exception {
this.request = new MockHttpServletRequest("GET", "");
this.request = new MockHttpServletRequest(MockServletContext.mvc(), "GET", "");
this.request.setMethod("GET");
this.response = new MockHttpServletResponse();
this.chain = new MockFilterChain();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -72,7 +72,7 @@ public class UrlAuthorizationConfigurerTests {
@BeforeEach
public void setup() {
this.request = new MockHttpServletRequest("GET", "");
this.request = new MockHttpServletRequest(MockServletContext.mvc(), "GET", "");
this.request.setMethod("GET");
this.response = new MockHttpServletResponse();
this.chain = new MockFilterChain();
+1 -1
View File
@@ -30,7 +30,7 @@ urls:
redirect_facility: httpd
ui:
bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.11/ui-bundle.zip
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.15/ui-bundle.zip
snapshot: true
runtime:
log:
@@ -188,6 +188,12 @@ open fun reactiveSessionRegistry(): ReactiveSessionRegistry {
When the maximum number of sessions is exceeded, by default, the least recently used session(s) will be expired.
If you want to change that behavior, you can <<concurrent-sessions-control-custom-strategy,customize the strategy used when the maximum number of sessions is exceeded>>.
[IMPORTANT]
====
The Concurrent Session Management is not aware if there is another session in some Identity Provider that you might use via xref:reactive/oauth2/login/index.adoc[OAuth 2 Login] for example.
If you also need to invalidate the session against the Identity Provider you must <<concurrent-sessions-control-custom-strategy,include your own implementation of `ServerMaximumSessionsExceededHandler`>>.
====
[[concurrent-sessions-control-custom-strategy]]
== Handling Maximum Number of Sessions Exceeded
@@ -10,6 +10,41 @@ However, despite using a username and password for authentication, it does not u
There are many different scenarios for how an LDAP server can be configured, so Spring Security's LDAP provider is fully configurable.
It uses separate strategy interfaces for authentication and role retrieval and provides default implementations, which can be configured to handle a wide range of situations.
[[servlet-authentication-ldap-required-dependencies]]
== Required Dependencies
To get started, add the `spring-security-ldap` dependency to your project.
When using Spring Boot, add the following dependencies:
.Spring Security LDAP Dependencies
[tabs]
======
Maven::
+
[source,xml,role="primary"]
----
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
----
Gradle::
+
[source,groovy,role="secondary"]
----
depenendencies {
implementation "org.springframework.boot:spring-boot-starter-data-ldap"
implementation "org.springframework.security:spring-security-ldap"
}
----
======
[[servlet-authentication-ldap-prerequisites]]
== Prerequisites
@@ -81,14 +116,14 @@ dn: cn=user,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: user
uniqueMember: uid=admin,ou=people,dc=springframework,dc=org
uniqueMember: uid=user,ou=people,dc=springframework,dc=org
member: uid=admin,ou=people,dc=springframework,dc=org
member: uid=user,ou=people,dc=springframework,dc=org
dn: cn=admin,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: admin
uniqueMember: uid=admin,ou=people,dc=springframework,dc=org
member: uid=admin,ou=people,dc=springframework,dc=org
----
[[servlet-authentication-ldap-unboundid]]
@@ -50,9 +50,9 @@ If you have more than one in your application context, you need to specify which
[[remember-me-persistent-token]]
== Persistent Token Approach
This approach is based on the article titled http://jaspan.com/improved_persistent_login_cookie_best_practice[http://jaspan.com/improved_persistent_login_cookie_best_practice], with some minor modifications. (Essentially, the username is not included in the cookie, to prevent exposing a valid login name unnecessarily.
There is a discussion on this in the comments section of this article.)
To use the this approach with namespace configuration, supply a datasource reference:
This approach is based on the article https://web.archive.org/web/20180819014446/http://jaspan.com/improved_persistent_login_cookie_best_practice[Improved Persistent Login Cookie Best Practice] with some minor modifications footnote:[Essentially, the username is not included in the cookie, to prevent exposing a valid login name unecessarily.
There is a discussion on this in the comments section of this article.].
To use this approach with namespace configuration, you would supply a datasource reference:
[source,xml]
----
@@ -241,8 +241,8 @@ Alternatively, you can modify every access constraint which requires the "user"
This can get quite complicated if you have a lot of different roles in your application.
The use of a role-hierarchy allows you to configure which roles (or authorities) should include others.
An extended version of Spring Security's `RoleVoter`, `RoleHierarchyVoter`, is configured with a `RoleHierarchy`, from which it obtains all the "reachable authorities" which the user is assigned.
A typical configuration might look like this:
This is supported for filter-based authorization in `HttpSecurity#authorizeHttpRequests` and for method-based authorization through `DefaultMethodSecurityExpressionHandler` for pre-post annotations, `SecuredAuthorizationManager` for `@Secured`, and `Jsr250AuthorizationManager` for JSR-250 annotations.
You can configure the behavior for all of them at once in the following way:
.Hierarchical Roles Configuration
[tabs]
@@ -260,7 +260,7 @@ static RoleHierarchy roleHierarchy() {
.build();
}
// and, if using method security also add
// and, if using pre-post method security also add
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
@@ -292,13 +292,10 @@ Xml::
----
======
[NOTE]
`RoleHierarchy` bean configuration is not yet ported over to `@EnableMethodSecurity`.
As such this example is using `AccessDecisionVoter`.
If you need `RoleHierarchy` support for method security, please continue using `@EnableGlobalMethodSecurity` until https://github.com/spring-projects/spring-security/issues/12783 is complete.
Here we have four roles in a hierarchy `ROLE_ADMIN => ROLE_STAFF => ROLE_USER => ROLE_GUEST`.
A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security constraints are evaluated against an `AuthorizationManager` adapted to call the above `RoleHierarchyVoter`.
A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security constraints are evaluated against any filter- or method-based rules.
[TIP]
The `>` symbol can be thought of as meaning "includes".
Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user.
@@ -185,15 +185,15 @@ Java::
[source,java,role="primary"]
----
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/endpoint").hasAuthority("USER")
.anyRequest().authenticated()
)
public SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/endpoint").hasAuthority("USER")
.anyRequest().authenticated()
)
// ...
return http.build();
return http.build();
}
----
@@ -202,14 +202,15 @@ Kotlin::
[source,kotlin,role="secondary"]
----
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http {
fun web(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize("/endpoint", hasAuthority("USER"))
authorize(anyRequest, authenticated)
}
}
return http.build();
}
return http.build()
}
----
@@ -1074,7 +1074,7 @@ class MethodSecurityConfig {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postAuthorize() {
return AuthorizationManagerBeforeMethodInterceptor.postAuthorize();
return AuthorizationManagerAfterMethodInterceptor.postAuthorize();
}
}
----
@@ -1089,7 +1089,7 @@ class MethodSecurityConfig {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun postAuthorize() : Advisor {
return AuthorizationManagerBeforeMethodInterceptor.postAuthorize()
return AuthorizationManagerAfterMethodInterceptor.postAuthorize()
}
}
----
@@ -179,8 +179,8 @@ Java::
[source=java,role="primary"]
----
@Bean
public HttpSessionEventListener sessionEventListener() {
return new HttpSessionEventListener();
public HttpSessionEventPublisher sessionEventPublisher() {
return new HttpSessionEventPublisher();
}
----
@@ -189,8 +189,8 @@ Kotlin::
[source=kotlin,role="secondary"]
----
@Bean
open fun sessionEventListener(): HttpSessionEventListener {
return HttpSessionEventListener()
open fun sessionEventPublisher(): HttpSessionEventPublisher {
return HttpSessionEventPublisher()
}
----
======
@@ -339,7 +339,7 @@ Java::
[source,java,role="primary"]
----
@Bean
JWTProcessor jwtProcessor(JWTClaimSetJWSKeySelector keySelector) {
JWTProcessor jwtProcessor(JWTClaimsSetAwareJWSKeySelector keySelector) {
ConfigurableJWTProcessor<SecurityContext> jwtProcessor =
new DefaultJWTProcessor();
jwtProcessor.setJWTClaimSetJWSKeySelector(keySelector);
+2 -2
View File
@@ -2,9 +2,9 @@
"dependencies": {
"antora": "3.2.0-alpha.4",
"@antora/atlas-extension": "1.0.0-alpha.2",
"@antora/collector-extension": "1.0.0-alpha.3",
"@antora/collector-extension": "1.0.0-alpha.4",
"@asciidoctor/tabs": "1.0.0-beta.6",
"@springio/antora-extensions": "1.10.0",
"@springio/antora-extensions": "1.11.1",
"@springio/asciidoctor-extensions": "1.0.0-alpha.10"
}
}
+1
View File
@@ -21,6 +21,7 @@
<property name="avoidStaticImportExcludes" value="org.springframework.security.web.util.matcher.AntPathRequestMatcher.*" />
<property name="avoidStaticImportExcludes" value="org.springframework.security.web.util.matcher.RegexRequestMatcher.*" />
<property name="avoidStaticImportExcludes" value="org.springframework.core.annotation.MergedAnnotations.SearchStrategy.*" />
<property name="avoidStaticImportExcludes" value="org.assertj.core.api.InstanceOfAssertFactories.*"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
+2 -2
View File
@@ -1,6 +1,6 @@
springBootVersion=3.1.1
version=6.3.0
samplesBranch=main
version=6.3.1
samplesBranch=6.3.x
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
+11 -11
View File
@@ -1,7 +1,7 @@
[versions]
com-squareup-okhttp3 = "3.14.9"
io-rsocket = "1.1.4"
io-spring-javaformat = "0.0.41"
io-spring-javaformat = "0.0.42"
io-spring-nohttp = "0.0.11"
jakarta-websocket = "2.1.1"
org-apache-directory-server = "1.5.5"
@@ -13,7 +13,7 @@ org-jetbrains-kotlin = "1.9.24"
org-jetbrains-kotlinx = "1.8.1"
org-mockito = "5.11.0"
org-opensaml = "4.3.2"
org-springframework = "6.1.7"
org-springframework = "6.1.9"
[libraries]
ch-qos-logback-logback-classic = "ch.qos.logback:logback-classic:1.5.6"
@@ -26,9 +26,9 @@ com-squareup-okhttp3-mockwebserver = { module = "com.squareup.okhttp3:mockwebser
com-squareup-okhttp3-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "com-squareup-okhttp3" }
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.6"
io-micrometer-micrometer-observation = "io.micrometer:micrometer-observation:1.12.7"
io-mockk = "io.mockk:mockk:1.13.11"
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.6"
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2023.0.7"
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" }
@@ -53,7 +53,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.6"
org-apache-maven-maven-resolver-provider = "org.apache.maven:maven-resolver-provider:3.9.7"
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" }
@@ -67,8 +67,8 @@ org-bouncycastle-bcprov-jdk15on = { module = "org.bouncycastle:bcprov-jdk18on",
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.4.8.Final"
org-hsqldb = "org.hsqldb:hsqldb:2.7.2"
org-hibernate-orm-hibernate-core = "org.hibernate.orm:hibernate-core:6.4.9.Final"
org-hsqldb = "org.hsqldb:hsqldb:2.7.3"
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.24"
org-jetbrains-kotlinx-kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "org-jetbrains-kotlinx" }
@@ -84,8 +84,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.13"
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2024.0.0"
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.3"
org-springframework-data-spring-data-bom = "org.springframework.data:spring-data-bom:2024.0.1"
org-springframework-ldap-spring-ldap-core = "org.springframework.ldap:spring-ldap-core:3.2.4"
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,11 +95,11 @@ net-sourceforge-saxon-saxon = "net.sourceforge.saxon:saxon:9.1.0.8"
org-yaml-snakeyaml = "org.yaml:snakeyaml:1.33"
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.3.0"
org-gretty-gretty = "org.gretty:gretty:4.1.3"
org-gretty-gretty = "org.gretty:gretty:4.1.4"
com-github-ben-manes-gradle-versions-plugin = "com.github.ben-manes:gradle-versions-plugin:0.51.0"
com-github-spullara-mustache-java-compiler = "com.github.spullara.mustache.java:compiler:0.9.13"
org-hidetake-gradle-ssh-plugin = "org.hidetake:gradle-ssh-plugin:2.10.1"
org-jfrog-buildinfo-build-info-extractor-gradle = "org.jfrog.buildinfo:build-info-extractor-gradle:4.33.15"
org-jfrog-buildinfo-build-info-extractor-gradle = "org.jfrog.buildinfo:build-info-extractor-gradle:4.33.19"
org-sonarsource-scanner-gradle-sonarqube-gradle-plugin = "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8.0.1969"
org-instancio-instancio-junit = "org.instancio:instancio-junit:3.7.1"
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -19,6 +19,7 @@ package org.springframework.security.messaging.web.csrf;
import java.util.Base64;
import org.springframework.security.crypto.codec.Utf8;
import org.springframework.util.Assert;
/**
* Copied from
@@ -43,26 +44,26 @@ final class XorCsrfTokenUtils {
byte[] tokenBytes = Utf8.encode(token);
int tokenSize = tokenBytes.length;
if (actualBytes.length < tokenSize) {
if (actualBytes.length != tokenSize * 2) {
return null;
}
// extract token and random bytes
int randomBytesSize = actualBytes.length - tokenSize;
byte[] xoredCsrf = new byte[tokenSize];
byte[] randomBytes = new byte[randomBytesSize];
byte[] randomBytes = new byte[tokenSize];
System.arraycopy(actualBytes, 0, randomBytes, 0, randomBytesSize);
System.arraycopy(actualBytes, randomBytesSize, xoredCsrf, 0, tokenSize);
System.arraycopy(actualBytes, 0, randomBytes, 0, tokenSize);
System.arraycopy(actualBytes, tokenSize, xoredCsrf, 0, tokenSize);
byte[] csrfBytes = xorCsrf(randomBytes, xoredCsrf);
return Utf8.decode(csrfBytes);
}
private static byte[] xorCsrf(byte[] randomBytes, byte[] csrfBytes) {
int len = Math.min(randomBytes.length, csrfBytes.length);
Assert.isTrue(randomBytes.length == csrfBytes.length, "arrays must be equal length");
int len = csrfBytes.length;
byte[] xoredCsrf = new byte[len];
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, csrfBytes.length);
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, len);
for (int i = 0; i < len; i++) {
xoredCsrf[i] ^= randomBytes[i];
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.security.messaging.web.csrf;
import java.util.Base64;
import java.util.HashMap;
import org.junit.jupiter.api.BeforeEach;
@@ -141,6 +142,73 @@ public class XorCsrfChannelInterceptorTests {
this.interceptor.preSend(message(), this.channel);
}
// gh-13310, gh-15184
@Test
public void preSendWhenCsrfBytesIsShorterThanRandomBytesThenThrowsInvalidCsrfTokenException() {
/*
* Token format: 3 random pad bytes + 2 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.messageHeaders.setNativeHeader(this.token.getHeaderName(), actualToken);
this.messageHeaders.getSessionAttributes().put(CsrfToken.class.getName(), this.token);
// @formatter:off
assertThatExceptionOfType(InvalidCsrfTokenException.class)
.isThrownBy(() -> this.interceptor.preSend(message(), mock(MessageChannel.class)));
// @formatter:on
}
// gh-13310, gh-15184
@Test
public void preSendWhenCsrfBytesIsLongerThanRandomBytesThenThrowsInvalidCsrfTokenException() {
/*
* Token format: 3 random pad bytes + 4 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99, 98, 97 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.messageHeaders.setNativeHeader(this.token.getHeaderName(), actualToken);
this.messageHeaders.getSessionAttributes().put(CsrfToken.class.getName(), this.token);
// @formatter:off
assertThatExceptionOfType(InvalidCsrfTokenException.class)
.isThrownBy(() -> this.interceptor.preSend(message(), mock(MessageChannel.class)));
// @formatter:on
}
// gh-13310, gh-15184
@Test
public void preSendWhenTokenBytesIsShorterThanActualBytesThenThrowsInvalidCsrfTokenException() {
this.messageHeaders.setNativeHeader(this.token.getHeaderName(), XOR_CSRF_TOKEN_VALUE);
CsrfToken csrfToken = new DefaultCsrfToken("header", "param", "a");
this.messageHeaders.getSessionAttributes().put(CsrfToken.class.getName(), csrfToken);
// @formatter:off
assertThatExceptionOfType(InvalidCsrfTokenException.class)
.isThrownBy(() -> this.interceptor.preSend(message(), mock(MessageChannel.class)));
// @formatter:on
}
// gh-13310, gh-15184
@Test
public void preSendWhenTokenBytesIsLongerThanActualBytesThenThrowsInvalidCsrfTokenException() {
this.messageHeaders.setNativeHeader(this.token.getHeaderName(), XOR_CSRF_TOKEN_VALUE);
CsrfToken csrfToken = new DefaultCsrfToken("header", "param", "abcde");
this.messageHeaders.getSessionAttributes().put(CsrfToken.class.getName(), csrfToken);
// @formatter:off
assertThatExceptionOfType(InvalidCsrfTokenException.class)
.isThrownBy(() -> this.interceptor.preSend(message(), mock(MessageChannel.class)));
// @formatter:on
}
// gh-13310, gh-15184
@Test
public void preSendWhenActualBytesIsEmptyThenThrowsInvalidCsrfTokenException() {
this.messageHeaders.setNativeHeader(this.token.getHeaderName(), "");
this.messageHeaders.getSessionAttributes().put(CsrfToken.class.getName(), this.token);
// @formatter:off
assertThatExceptionOfType(InvalidCsrfTokenException.class)
.isThrownBy(() -> this.interceptor.preSend(message(), mock(MessageChannel.class)));
// @formatter:on
}
private Message<String> message() {
return MessageBuilder.withPayload("message").copyHeaders(this.messageHeaders.toMap()).build();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2024 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.
@@ -94,14 +94,10 @@ public final class WebSessionServerOAuth2AuthorizedClientRepository implements S
// @formatter:on
}
@SuppressWarnings("unchecked")
private Map<String, OAuth2AuthorizedClient> getAuthorizedClients(WebSession session) {
Map<String, OAuth2AuthorizedClient> authorizedClients = (session != null)
? (Map<String, OAuth2AuthorizedClient>) session.getAttribute(this.sessionAttributeName) : null;
if (authorizedClients == null) {
authorizedClients = new HashMap<>();
}
return authorizedClients;
Assert.notNull(session, "session cannot be null");
Map<String, OAuth2AuthorizedClient> authorizedClients = session.getAttribute(this.sessionAttributeName);
return (authorizedClients != null) ? authorizedClients : new HashMap<>();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2024 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.
@@ -17,6 +17,7 @@
package org.springframework.security.oauth2.client.web.server;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
@@ -24,10 +25,12 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
@@ -202,4 +205,28 @@ public class WebSessionServerOAuth2AuthorizedClientRepositoryTests {
assertThat(loadedAuthorizedClient2).isSameAs(authorizedClient2);
}
@Test
public void saveAuthorizedClientWhenSessionIsNullThenThrowIllegalArgumentException() {
ServerWebExchange exchange = mock(ServerWebExchange.class);
given(exchange.getSession()).willReturn(Mono.empty());
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration1, this.principalName1,
mock(OAuth2AccessToken.class));
// @formatter:off
assertThatIllegalArgumentException()
.isThrownBy(() -> this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, null, exchange).block())
.withMessage("session cannot be null");
// @formatter:on
}
@Test
public void removeAuthorizedClientWhenSessionIsNullThenThrowIllegalArgumentException() {
ServerWebExchange exchange = mock(ServerWebExchange.class);
given(exchange.getSession()).willReturn(Mono.empty());
// @formatter:off
assertThatIllegalArgumentException()
.isThrownBy(() -> this.authorizedClientRepository.removeAuthorizedClient(this.registrationId1, null, exchange).block())
.withMessage("session cannot be null");
// @formatter:on
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -183,7 +183,7 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
return claims;
}
private OAuth2TokenIntrospectionClaimAccessor convertClaimsSet(Map<String, Object> claims) {
private ArrayListFromStringClaimAccessor convertClaimsSet(Map<String, Object> claims) {
Map<String, Object> converted = new LinkedHashMap<>(claims);
converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
if (v instanceof String) {
@@ -277,4 +277,18 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
}
// gh-15165
private interface ArrayListFromStringClaimAccessor extends OAuth2TokenIntrospectionClaimAccessor {
@Override
default List<String> getScopes() {
Object value = getClaims().get(OAuth2TokenIntrospectionClaimNames.SCOPE);
if (value instanceof ArrayListFromString list) {
return list;
}
return OAuth2TokenIntrospectionClaimAccessor.super.getScopes();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -143,7 +143,7 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
.switchIfEmpty(Mono.error(() -> new BadOpaqueTokenException("Provided token isn't active")));
}
private OAuth2TokenIntrospectionClaimAccessor convertClaimsSet(Map<String, Object> claims) {
private ArrayListFromStringClaimAccessor convertClaimsSet(Map<String, Object> claims) {
Map<String, Object> converted = new LinkedHashMap<>(claims);
converted.computeIfPresent(OAuth2TokenIntrospectionClaimNames.AUD, (k, v) -> {
if (v instanceof String) {
@@ -231,4 +231,18 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
}
// gh-15165
private interface ArrayListFromStringClaimAccessor extends OAuth2TokenIntrospectionClaimAccessor {
@Override
default List<String> getScopes() {
Object value = getClaims().get(OAuth2TokenIntrospectionClaimNames.SCOPE);
if (value instanceof ArrayListFromString list) {
return list;
}
return OAuth2TokenIntrospectionClaimAccessor.super.getScopes();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -39,6 +39,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimAccessor;
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames;
@@ -245,6 +246,21 @@ public class SpringOpaqueTokenIntrospectorTests {
assertThat(scope).containsExactly("read", "write", "dolphin");
}
// gh-15165
@Test
public void introspectWhenActiveThenMapsAuthorities() {
RestOperations restOperations = mock(RestOperations.class);
OpaqueTokenIntrospector introspectionClient = new SpringOpaqueTokenIntrospector(INTROSPECTION_URL,
restOperations);
given(restOperations.exchange(any(RequestEntity.class), eq(STRING_OBJECT_MAP))).willReturn(ACTIVE);
OAuth2AuthenticatedPrincipal principal = introspectionClient.introspect("token");
assertThat(principal.getAuthorities()).isNotEmpty();
Collection<String> scope = principal.getAttribute("scope");
assertThat(scope).containsExactly("read", "write", "dolphin");
Collection<String> authorities = AuthorityUtils.authorityListToSet(principal.getAuthorities());
assertThat(authorities).containsExactly("SCOPE_read", "SCOPE_write", "SCOPE_dolphin");
}
@Test
public void constructorWhenIntrospectionUriIsNullThenIllegalArgumentException() {
assertThatIllegalArgumentException()
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -37,6 +38,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimAccessor;
import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames;
@@ -197,6 +199,20 @@ public class SpringReactiveOpaqueTokenIntrospectorTests {
// @formatter:on
}
// gh-15165
@Test
public void introspectWhenActiveThenMapsAuthorities() {
WebClient webClient = mockResponse(ACTIVE_RESPONSE);
SpringReactiveOpaqueTokenIntrospector introspectionClient = new SpringReactiveOpaqueTokenIntrospector(
INTROSPECTION_URL, webClient);
OAuth2AuthenticatedPrincipal principal = introspectionClient.introspect("token").block();
assertThat(principal.getAuthorities()).isNotEmpty();
Collection<String> scope = principal.getAttribute("scope");
assertThat(scope).containsExactly("read", "write", "dolphin");
Collection<String> authorities = AuthorityUtils.authorityListToSet(principal.getAuthorities());
assertThat(authorities).containsExactly("SCOPE_read", "SCOPE_write", "SCOPE_dolphin");
}
@Test
public void setAuthenticationConverterWhenConverterIsNullThenExceptionIsThrown() {
WebClient web = mock(WebClient.class);
@@ -47,6 +47,7 @@ import org.opensaml.core.xml.schema.XSDateTime;
import org.opensaml.core.xml.schema.XSInteger;
import org.opensaml.core.xml.schema.XSString;
import org.opensaml.core.xml.schema.XSURI;
import org.opensaml.saml.common.assertion.AssertionValidationException;
import org.opensaml.saml.common.assertion.ValidationContext;
import org.opensaml.saml.common.assertion.ValidationResult;
import org.opensaml.saml.saml2.assertion.ConditionValidator;
@@ -858,6 +859,13 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
static SAML20AssertionValidator createSignatureValidator(SignatureTrustEngine engine) {
return new SAML20AssertionValidator(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null, engine,
validator) {
@Nonnull
@Override
protected ValidationResult validateBasicData(@Nonnull Assertion assertion,
@Nonnull ValidationContext context) throws AssertionValidationException {
return ValidationResult.VALID;
}
@Nonnull
@Override
protected ValidationResult validateConditions(Assertion assertion, ValidationContext context) {
@@ -847,6 +847,20 @@ public class OpenSaml4AuthenticationProviderTests {
provider.authenticate(token);
}
// gh-15022
@Test
public void authenticateWhenClockSkewThenVerifiesSignature() {
OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();
provider.setAssertionValidator(OpenSaml4AuthenticationProvider.createDefaultAssertionValidatorWithParameters(
(params) -> params.put(SAML2AssertionValidationParameters.CLOCK_SKEW, Duration.ofMinutes(10))));
Response response = response();
Assertion assertion = assertion();
assertion.setIssueInstant(Instant.now().plus(Duration.ofMinutes(9)));
response.getAssertions().add(assertion);
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
provider.authenticate(token);
}
private <T extends XMLObject> T build(QName qName) {
return (T) XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(qName).buildObject(qName);
}
+1 -1
View File
@@ -5,7 +5,7 @@ pluginManagement {
}
plugins {
id "com.gradle.develocity" version "3.17.4"
id "com.gradle.develocity" version "3.17.5"
id "io.spring.ge.conventions" version "0.0.17"
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2024 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.
@@ -27,11 +27,13 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.log.LogMessage;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.StringUtils;
/**
* Standard implementation of {@code SecurityFilterChain}.
*
* @author Luke Taylor
* @author Jinwoo Bae
* @since 3.1
*/
public final class DefaultSecurityFilterChain implements SecurityFilterChain {
@@ -48,10 +50,15 @@ public final class DefaultSecurityFilterChain implements SecurityFilterChain {
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
if (filters.isEmpty()) {
logger.info(LogMessage.format("Will not secure %s", requestMatcher));
logger.debug(LogMessage.format("Will not secure %s", requestMatcher));
}
else {
logger.info(LogMessage.format("Will secure %s with %s", requestMatcher, filters));
List<String> filterNames = new ArrayList<>();
for (Filter filter : filters) {
filterNames.add(filter.getClass().getSimpleName());
}
String names = StringUtils.collectionToDelimitedString(filterNames, ", ");
logger.debug(LogMessage.format("Will secure %s with filters: %s", requestMatcher, names));
}
this.requestMatcher = requestMatcher;
this.filters = new ArrayList<>(filters);
@@ -32,8 +32,8 @@ import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.util.Assert;
/**
* {@link RememberMeServices} implementation based on Barry Jaspan's
* <a href="http://jaspan.com/improved_persistent_login_cookie_best_practice">Improved
* {@link RememberMeServices} implementation based on Barry Jaspan's <a href=
* "https://web.archive.org/web/20180819014446/http://jaspan.com/improved_persistent_login_cookie_best_practice">Improved
* Persistent Login Cookie Best Practice</a>.
*
* There is a slight modification to the described approach, in that the username is not
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -84,20 +84,19 @@ public final class XorCsrfTokenRequestAttributeHandler extends CsrfTokenRequestA
byte[] tokenBytes = Utf8.encode(token);
int tokenSize = tokenBytes.length;
if (actualBytes.length < tokenSize) {
if (actualBytes.length != tokenSize * 2) {
return null;
}
// extract token and random bytes
int randomBytesSize = actualBytes.length - tokenSize;
byte[] xoredCsrf = new byte[tokenSize];
byte[] randomBytes = new byte[randomBytesSize];
byte[] randomBytes = new byte[tokenSize];
System.arraycopy(actualBytes, 0, randomBytes, 0, randomBytesSize);
System.arraycopy(actualBytes, randomBytesSize, xoredCsrf, 0, tokenSize);
System.arraycopy(actualBytes, 0, randomBytes, 0, tokenSize);
System.arraycopy(actualBytes, tokenSize, xoredCsrf, 0, tokenSize);
byte[] csrfBytes = xorCsrf(randomBytes, xoredCsrf);
return (csrfBytes != null) ? Utf8.decode(csrfBytes) : null;
return Utf8.decode(csrfBytes);
}
private static String createXoredCsrfToken(SecureRandom secureRandom, String token) {
@@ -114,12 +113,10 @@ public final class XorCsrfTokenRequestAttributeHandler extends CsrfTokenRequestA
}
private static byte[] xorCsrf(byte[] randomBytes, byte[] csrfBytes) {
if (csrfBytes.length < randomBytes.length) {
return null;
}
int len = Math.min(randomBytes.length, csrfBytes.length);
Assert.isTrue(randomBytes.length == csrfBytes.length, "arrays must be equal length");
int len = csrfBytes.length;
byte[] xoredCsrf = new byte[len];
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, csrfBytes.length);
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, len);
for (int i = 0; i < len; i++) {
xoredCsrf[i] ^= randomBytes[i];
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -77,17 +77,16 @@ public final class XorServerCsrfTokenRequestAttributeHandler extends ServerCsrfT
byte[] tokenBytes = Utf8.encode(token);
int tokenSize = tokenBytes.length;
if (actualBytes.length < tokenSize) {
if (actualBytes.length != tokenSize * 2) {
return null;
}
// extract token and random bytes
int randomBytesSize = actualBytes.length - tokenSize;
byte[] xoredCsrf = new byte[tokenSize];
byte[] randomBytes = new byte[randomBytesSize];
byte[] randomBytes = new byte[tokenSize];
System.arraycopy(actualBytes, 0, randomBytes, 0, randomBytesSize);
System.arraycopy(actualBytes, randomBytesSize, xoredCsrf, 0, tokenSize);
System.arraycopy(actualBytes, 0, randomBytes, 0, tokenSize);
System.arraycopy(actualBytes, tokenSize, xoredCsrf, 0, tokenSize);
byte[] csrfBytes = xorCsrf(randomBytes, xoredCsrf);
return (csrfBytes != null) ? Utf8.decode(csrfBytes) : null;
@@ -107,12 +106,10 @@ public final class XorServerCsrfTokenRequestAttributeHandler extends ServerCsrfT
}
private static byte[] xorCsrf(byte[] randomBytes, byte[] csrfBytes) {
if (csrfBytes.length < randomBytes.length) {
return null;
}
int len = Math.min(randomBytes.length, csrfBytes.length);
Assert.isTrue(randomBytes.length == csrfBytes.length, "arrays must be equal length");
int len = csrfBytes.length;
byte[] xoredCsrf = new byte[len];
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, csrfBytes.length);
System.arraycopy(csrfBytes, 0, xoredCsrf, 0, len);
for (int i = 0; i < len; i++) {
xoredCsrf[i] ^= randomBytes[i];
}
@@ -18,6 +18,7 @@ package org.springframework.security.web.util.matcher;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import jakarta.servlet.http.HttpServletRequest;
@@ -47,7 +48,7 @@ public final class IpAddressMatcher implements RequestMatcher {
* come.
*/
public IpAddressMatcher(String ipAddress) {
assertStartsWithHexa(ipAddress);
assertNotHostName(ipAddress);
if (ipAddress.indexOf('/') > 0) {
String[] addressAndMask = StringUtils.split(ipAddress, "/");
ipAddress = addressAndMask[0];
@@ -68,7 +69,7 @@ public final class IpAddressMatcher implements RequestMatcher {
}
public boolean matches(String address) {
assertStartsWithHexa(address);
assertNotHostName(address);
InetAddress remoteAddress = parseAddress(address);
if (!this.requiredAddress.getClass().equals(remoteAddress.getClass())) {
return false;
@@ -91,11 +92,17 @@ public final class IpAddressMatcher implements RequestMatcher {
return true;
}
private void assertStartsWithHexa(String ipAddress) {
Assert.isTrue(
ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
|| Character.digit(ipAddress.charAt(0), 16) != -1,
"ipAddress must start with a [, :, or a hexadecimal digit");
private void assertNotHostName(String ipAddress) {
String error = "ipAddress " + ipAddress + " doesn't look like an IP Address. Is it a host name?";
Assert.isTrue(ipAddress.charAt(0) == '[' || ipAddress.charAt(0) == ':'
|| Character.digit(ipAddress.charAt(0), 16) != -1, error);
if (!ipAddress.contains(":")) {
Scanner parts = new Scanner(ipAddress);
parts.useDelimiter("[./]");
while (parts.hasNext()) {
Assert.isTrue(parts.hasNextInt() && parts.nextInt() >> 8 == 0, error);
}
}
}
private InetAddress parseAddress(String address) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -44,6 +44,9 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/
public class XorCsrfTokenRequestAttributeHandlerTests {
/*
* Token format: 3 random pad bytes + 3 padded bytes.
*/
private static final byte[] XOR_CSRF_TOKEN_BYTES = new byte[] { 1, 1, 1, 96, 99, 98 };
private static final String XOR_CSRF_TOKEN_VALUE = Base64.getEncoder().encodeToString(XOR_CSRF_TOKEN_BYTES);
@@ -208,14 +211,58 @@ public class XorCsrfTokenRequestAttributeHandlerTests {
assertThat(tokenValue).isEqualTo(this.token.getToken());
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenIsInvalidThenReturnsNull() {
public void resolveCsrfTokenValueWhenCsrfBytesIsShorterThanRandomBytesThenReturnsNull() {
/*
* Token format: 3 random pad bytes + 2 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.request.setParameter(this.token.getParameterName(), actualToken);
String tokenValue = this.handler.resolveCsrfTokenValue(this.request, this.token);
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenCsrfBytesIsLongerThanRandomBytesThenReturnsNull() {
/*
* Token format: 3 random pad bytes + 4 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99, 98, 97 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.request.setParameter(this.token.getParameterName(), actualToken);
String tokenValue = this.handler.resolveCsrfTokenValue(this.request, this.token);
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenTokenBytesIsShorterThanActualBytesThenReturnsNull() {
this.request.setParameter(this.token.getParameterName(), XOR_CSRF_TOKEN_VALUE);
CsrfToken csrfToken = new DefaultCsrfToken("headerName", "paramName", "a");
String tokenValue = this.handler.resolveCsrfTokenValue(this.request, csrfToken);
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenTokenBytesIsLongerThanActualBytesThenReturnsNull() {
this.request.setParameter(this.token.getParameterName(), XOR_CSRF_TOKEN_VALUE);
CsrfToken csrfToken = new DefaultCsrfToken("headerName", "paramName", "abcde");
String tokenValue = this.handler.resolveCsrfTokenValue(this.request, csrfToken);
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenActualBytesIsEmptyThenReturnsNull() {
this.request.setParameter(this.token.getParameterName(), "");
String tokenValue = this.handler.resolveCsrfTokenValue(this.request, this.token);
assertThat(tokenValue).isNull();
}
private static Answer<Void> fillByteArray() {
return (invocation) -> {
byte[] bytes = invocation.getArgument(0);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -46,6 +46,9 @@ import static org.mockito.Mockito.verify;
*/
public class XorServerCsrfTokenRequestAttributeHandlerTests {
/*
* Token format: 3 random pad bytes + 3 padded bytes.
*/
private static final byte[] XOR_CSRF_TOKEN_BYTES = new byte[] { 1, 1, 1, 96, 99, 98 };
private static final String XOR_CSRF_TOKEN_VALUE = Base64.getEncoder().encodeToString(XOR_CSRF_TOKEN_BYTES);
@@ -188,16 +191,76 @@ public class XorServerCsrfTokenRequestAttributeHandlerTests {
StepVerifier.create(csrfToken).expectNext(this.token.getToken()).verifyComplete();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenIsInvalidThenReturnsNull() {
public void resolveCsrfTokenValueWhenCsrfBytesIsShorterThanRandomBytesThenReturnsNull() {
/*
* Token format: 3 random pad bytes + 2 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.exchange = MockServerWebExchange
.builder(MockServerHttpRequest.post("/")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.body(this.token.getParameterName() + "=" + XOR_CSRF_TOKEN_VALUE))
.header(this.token.getHeaderName(), actualToken))
.build();
CsrfToken token = new DefaultCsrfToken("headerName", "paramName", "a");
Mono<String> csrfToken = this.handler.resolveCsrfTokenValue(this.exchange, token);
assertThat(csrfToken.block()).isNull();
String tokenValue = this.handler.resolveCsrfTokenValue(this.exchange, this.token).block();
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenCsrfBytesIsLongerThanRandomBytesThenReturnsNull() {
/*
* Token format: 3 random pad bytes + 4 padded bytes.
*/
byte[] actualBytes = { 1, 1, 1, 96, 99, 98, 97 };
String actualToken = Base64.getEncoder().encodeToString(actualBytes);
this.exchange = MockServerWebExchange
.builder(MockServerHttpRequest.post("/")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(this.token.getHeaderName(), actualToken))
.build();
String tokenValue = this.handler.resolveCsrfTokenValue(this.exchange, this.token).block();
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenTokenBytesIsShorterThanActualBytesThenReturnsNull() {
this.exchange = MockServerWebExchange
.builder(MockServerHttpRequest.post("/")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(this.token.getHeaderName(), XOR_CSRF_TOKEN_VALUE))
.build();
CsrfToken csrfToken = new DefaultCsrfToken("headerName", "paramName", "a");
String tokenValue = this.handler.resolveCsrfTokenValue(this.exchange, csrfToken).block();
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenTokenBytesIsLongerThanActualBytesThenReturnsNull() {
this.exchange = MockServerWebExchange
.builder(MockServerHttpRequest.post("/")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(this.token.getHeaderName(), XOR_CSRF_TOKEN_VALUE))
.build();
CsrfToken csrfToken = new DefaultCsrfToken("headerName", "paramName", "abcde");
String tokenValue = this.handler.resolveCsrfTokenValue(this.exchange, csrfToken).block();
assertThat(tokenValue).isNull();
}
// gh-13310, gh-15184
@Test
public void resolveCsrfTokenValueWhenActualBytesIsEmptyThenReturnsNull() {
this.exchange = MockServerWebExchange
.builder(MockServerHttpRequest.post("/")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(this.token.getHeaderName(), ""))
.build();
String tokenValue = this.handler.resolveCsrfTokenValue(this.exchange, this.token).block();
assertThat(tokenValue).isNull();
}
private static Answer<Void> fillByteArray() {
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
@@ -108,7 +109,21 @@ public class IpAddressMatcherTests {
@Test
public void invalidAddressThenIllegalArgumentException() {
assertThatIllegalArgumentException().isThrownBy(() -> new IpAddressMatcher("invalid-ip"))
.withMessage("ipAddress must start with a [, :, or a hexadecimal digit");
.withMessage("ipAddress invalid-ip doesn't look like an IP Address. Is it a host name?");
}
// gh-15172
@Test
public void hexadecimalDomainNameThenIllegalArgumentException() {
assertThatException().isThrownBy(() -> new IpAddressMatcher("deadbeef.abc"))
.withMessage("ipAddress deadbeef.abc doesn't look like an IP Address. Is it a host name?");
}
// gh-15172
@Test
public void numericDomainNameThenIllegalArgumentException() {
assertThatException().isThrownBy(() -> new IpAddressMatcher("123.156.7.18.org"))
.withMessage("ipAddress 123.156.7.18.org doesn't look like an IP Address. Is it a host name?");
}
}