chore(springboot): upgrade to Spring Boot 4 / Spring Security 7 and fix 5 SDK bugs#248
chore(springboot): upgrade to Spring Boot 4 / Spring Security 7 and fix 5 SDK bugs#248KomanRudden wants to merge 15 commits into
Conversation
…ix 5 SDK bugs (token exchange RestClient, audience validator, RP-Initiated logout conditional, starter OAuth2 starters, test API renames) Co-authored-by: Cursor <cursoragent@cursor.com>
Adds a README to kinde-report-aggregate clarifying that it is not a library but a JaCoCo coverage aggregator following the official JaCoCo example recipe. Covers: why a dedicated module is needed (jacoco:report-aggregate can only read .exec files from declared deps), how to run it (mvn verify), where the output lands, how CI consumes it, why the empty ReportTest.java exists, and the artifactId/excludeArtifact contract with the root pom. Co-authored-by: Cursor <cursoragent@cursor.com>
Tidy-up pass over things noticed after the Spring Boot 4 upgrade landed.
No behaviour change.
* playground/thymeleaf-full application.properties: replace hardcoded
https://koman.kinde.com URIs with ${KINDE_PREFIX} parameterisation
(consistent with the rest of the file) and drop the unused logout-uri
property (no Java code reads it).
* KindeOAuth2Properties javadoc: fix the misleading WebFlux redirect
URI note (it is not always /login/oauth2/code/okta - the path is
derived from the registration id, which is "kinde" for Kinde apps)
and replace the oktapreview.com example for the "domain" property
with a Kinde-shaped one.
* UserUtil: rename "Okta reg" -> "Kinde registration" in comments.
* TokenUtil: drop "Okta" prefix from the isRootOrgIssuer log messages.
They still describe the same two cases (custom vs root/org issuer)
but no longer claim it as Okta-specific terminology.
* KindeOAuth2PropertiesMappingEnvironmentPostProcessor: rename the
"okta-scope-remaper" property source to "kinde-scope-remapper"
(also fixes a typo) and update an inline comment.
* MIGRATION.md: add a "V 2.x (Spring Boot 3) to V 2.2 (Spring Boot 4)"
section covering the Java 17 baseline, the audience-validator
opt-in behaviour change, the okta.* -> kinde.* logout property
rename, the new transitive deps in kinde-springboot-starter, and a
pointer to the Spring Security 7 migration guide.
Verified: kinde-springboot-core tests still 52/52 green.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughCentralize BOM/version management for Spring Boot 4 and Spring Security 7; migrate servlet and reactive security DSLs to Customizer lambda style; replace RestTemplate token exchange with RestClient; add RestClient builder; update Kinde properties/docs and imports; expand tests and add playground API/debug endpoints. ChangesSpring Boot 4 and Spring Security 7 Upgrade
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/TokenUtilTest.java (1)
41-44: 💤 Low valueConsider removing redundant test.
The original
testJwtValidatormethod provides minimal coverage (only verifies no exception is thrown). The new comprehensive test suite (lines 46-103) thoroughly covers JWT validation behavior with multiple scenarios and assertions, making this test redundant.♻️ Suggested cleanup
- `@Test` - public void testJwtValidator() throws Exception { - TokenUtil.jwtValidator("Kinde","test.com"); - } -🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/TokenUtilTest.java` around lines 41 - 44, Remove the redundant no-op test method testJwtValidator in TokenUtilTest: delete the `@Test` method that simply calls TokenUtil.jwtValidator("Kinde","test.com") since the newer tests (lines covering 46-103) already exercise JWT validation with assertions; this cleanup keeps the test suite focused and avoids duplicate/meaningless checks while leaving other TokenUtil-related tests intact.kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.java (1)
27-36: 💤 Low valueConsider adding negative assertions to strengthen noop verification.
The test verifies that
initdoesn't throw when noKindeOAuth2Propertiesbeans exist, but it doesn't assert that the configurer actually short-circuits. Adding a verification that OAuth2-related methods onHttpSecurityare NOT called would provide stronger confidence that the noop path is taken.🔍 Optional enhancement with negative verification
configurer.init(httpSecurity); + + // Verify that oauth2Login was never called (confirming short-circuit) + verify(httpSecurity, never()).oauth2Login(any()); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.java` around lines 27 - 36, Add negative verifications to the test so it asserts init actually short-circuits: after calling KindeOAuth2Configurer.init(httpSecurity) verify that OAuth2-related configuration methods on the mocked HttpSecurity were not invoked (for example verify(httpSecurity, never()).oauth2Login() and verify(httpSecurity, never()).oauth2Client() or other OAuth2 entry points used by KindeOAuth2Configurer). This ensures the noop path is validated in addition to "no exception" behavior.kinde-springboot/kinde-springboot-starter/pom.xml (1)
108-121: ⚡ Quick winUse the Boot 4 starter names here.
Spring Boot 4.0.6 documents
spring-boot-starter-oauth2-clientandspring-boot-starter-oauth2-resource-serveras deprecated in favor ofspring-boot-starter-security-oauth2-clientandspring-boot-starter-security-oauth2-resource-server. Publishing the old coordinates from this starter pushes deprecated dependencies onto every consumer. (docs.spring.io)♻️ Proposed fix
<dependency> <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-oauth2-client</artifactId> + <artifactId>spring-boot-starter-security-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> + <artifactId>spring-boot-starter-security-oauth2-resource-server</artifactId> </dependency>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-starter/pom.xml` around lines 108 - 121, Replace the deprecated Spring Boot 4 artifactIds in the POM: change the dependency artifactId "spring-boot-starter-oauth2-client" to "spring-boot-starter-security-oauth2-client" and change "spring-boot-starter-oauth2-resource-server" to "spring-boot-starter-security-oauth2-resource-server" so consumers of this starter do not inherit deprecated coordinates; keep the same groupId (org.springframework.boot) and other dependency elements intact.kinde-springboot/kinde-springboot-core/pom.xml (1)
72-97: ⚡ Quick winRemove the per-artifact Jackson pins.
spring-boot-dependencies4.0.6 already managesjackson-annotationsat2.21and the rest of this Jackson family at2.21.2, so restating each artifact here just creates another place for version drift during the next Boot/Jackson bump. (docs.spring.io)♻️ Proposed simplification
<dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>jackson-bom</artifactId> <version>2.21.2</version> <type>pom</type> <scope>import</scope> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-core</artifactId> - <version>2.21.2</version> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - <!-- jackson-annotations dropped the patch number in 2.21. --> - <version>2.21</version> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <version>2.21.2</version> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.datatype</groupId> - <artifactId>jackson-datatype-joda</artifactId> - <version>2.21.2</version> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.datatype</groupId> - <artifactId>jackson-datatype-jsr310</artifactId> - <version>2.21.2</version> - </dependency>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-core/pom.xml` around lines 72 - 97, The POM currently hard-pins Jackson artifacts (jackson-core, jackson-annotations, jackson-databind, jackson-datatype-joda, jackson-datatype-jsr310) which duplicates versions already provided by spring-boot-dependencies; remove the explicit <version> elements for those <dependency> entries (or remove the dependency entries entirely if they are unused) so the BOM-managed versions are used instead, keeping the artifactId/groupId entries (e.g., jackson-core, jackson-annotations, jackson-databind, jackson-datatype-joda, jackson-datatype-jsr310) to let Spring Boot manage the versions and avoid future drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@kinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2Configurer.java`:
- Around line 41-45: The null-checks on issuer and client id are unsafe because
getIssuerUri() and getClientId() can be null; update the condition in
KindeOAuth2Configurer to use null-safe checks (e.g., Spring's
StringUtils.hasText(...) or explicit null + empty checks) for
propertiesProvider.getIssuerUri() and propertiesRegistration.getClientId(), and
keep the existing null checks for propertiesProvider and propertiesRegistration;
ensure you call StringUtils.hasText(propertiesProvider.getIssuerUri()) and
StringUtils.hasText(propertiesRegistration.getClientId()) (or equivalent != null
&& !isEmpty()) instead of .isEmpty() to avoid NPEs.
In
`@kinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/TokenUtil.java`:
- Around line 80-85: The validators lambda currently calls
Collections.disjoint(token.getAudience(), expectedAudience) without checking for
null, which can throw when token.getAudience() is null; update the validator
(the lambda added to validators) to first obtain the audience into a local
variable (e.g., List<String> tokenAudience = token.getAudience()) and treat null
as empty (or explicitly return
OAuth2TokenValidatorResult.failure(INVALID_AUDIENCE) when tokenAudience is null
or empty) before calling Collections.disjoint; ensure the final return still
yields OAuth2TokenValidatorResult.success() when there is an intersection and
OAuth2TokenValidatorResult.failure(INVALID_AUDIENCE) otherwise.
In
`@kinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/UserUtil.java`:
- Line 54: The check in UserUtil using
userRequest.getClientRegistration().getRegistrationId() is currently
case-sensitive while the OAuth2 path uses a case-insensitive rule; update the
comparison in the UserUtil decorate branch to use a case-insensitive match
(e.g., compare lowercase or use equalsIgnoreCase) against "kinde" so both
decorate paths use the same registration-id matching logic and ensure any other
decoration branch that checks the registrationId follows the same
equalsIgnoreCase approach.
---
Nitpick comments:
In `@kinde-springboot/kinde-springboot-core/pom.xml`:
- Around line 72-97: The POM currently hard-pins Jackson artifacts
(jackson-core, jackson-annotations, jackson-databind, jackson-datatype-joda,
jackson-datatype-jsr310) which duplicates versions already provided by
spring-boot-dependencies; remove the explicit <version> elements for those
<dependency> entries (or remove the dependency entries entirely if they are
unused) so the BOM-managed versions are used instead, keeping the
artifactId/groupId entries (e.g., jackson-core, jackson-annotations,
jackson-databind, jackson-datatype-joda, jackson-datatype-jsr310) to let Spring
Boot manage the versions and avoid future drift.
In
`@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.java`:
- Around line 27-36: Add negative verifications to the test so it asserts init
actually short-circuits: after calling KindeOAuth2Configurer.init(httpSecurity)
verify that OAuth2-related configuration methods on the mocked HttpSecurity were
not invoked (for example verify(httpSecurity, never()).oauth2Login() and
verify(httpSecurity, never()).oauth2Client() or other OAuth2 entry points used
by KindeOAuth2Configurer). This ensures the noop path is validated in addition
to "no exception" behavior.
In
`@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/TokenUtilTest.java`:
- Around line 41-44: Remove the redundant no-op test method testJwtValidator in
TokenUtilTest: delete the `@Test` method that simply calls
TokenUtil.jwtValidator("Kinde","test.com") since the newer tests (lines covering
46-103) already exercise JWT validation with assertions; this cleanup keeps the
test suite focused and avoids duplicate/meaningless checks while leaving other
TokenUtil-related tests intact.
In `@kinde-springboot/kinde-springboot-starter/pom.xml`:
- Around line 108-121: Replace the deprecated Spring Boot 4 artifactIds in the
POM: change the dependency artifactId "spring-boot-starter-oauth2-client" to
"spring-boot-starter-security-oauth2-client" and change
"spring-boot-starter-oauth2-resource-server" to
"spring-boot-starter-security-oauth2-resource-server" so consumers of this
starter do not inherit deprecated coordinates; keep the same groupId
(org.springframework.boot) and other dependency elements intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d104ddac-d750-4091-b7c6-d981e34deae4
⛔ Files ignored due to path filters (8)
.gitignoreis excluded by none and included by noneMIGRATION.mdis excluded by!**/*.mdand included by nonekinde-report-aggregate/README.mdis excluded by!**/README.md,!**/*.mdand included by noneplayground/kinde-springboot-pkce-client-example/src/main/resources/application.yamlis excluded by!**/application.yamland included by**/*.yamlplayground/kinde-springboot-starter-example/src/main/resources/application.yamlis excluded by!**/application.yamland included by**/*.yamlplayground/kinde-springboot-starter-example/src/main/resources/templates/home.htmlis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/.envis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/src/main/resources/application.propertiesis excluded by!**/application.propertiesand included by none
📒 Files selected for processing (29)
kinde-springboot/kinde-springboot-core/pom.xmlkinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/Kinde.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2AutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2Configurer.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/ReactiveKindeOAuth2AutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/ReactiveKindeOAuth2ResourceServerAutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/ReactiveKindeOAuth2ResourceServerHttpServerAutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/ReactiveKindeOAuth2ServerHttpServerAutoConfig.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/TokenUtil.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/UserUtil.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/config/KindeOAuth2Properties.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/env/KindeOAuth2PropertiesMappingEnvironmentPostProcessor.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2AutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2ResourceServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/TokenUtilTest.javakinde-springboot/kinde-springboot-starter/pom.xmlplayground/kinde-springboot-pkce-client-example/pom.xmlplayground/kinde-springboot-starter-example/pom.xmlplayground/kinde-springboot-starter-example/src/main/java/com/kinde/spring/KindeClientApplication.javaplayground/kinde-springboot-starter-example/src/main/java/com/kinde/spring/config/SecurityConfig.javaplayground/kinde-springboot-starter-example/src/main/java/com/kinde/spring/controllers/ApiController.javaplayground/kinde-springboot-starter-example/src/main/java/com/kinde/spring/controllers/DebugController.javaplayground/kinde-springboot-thymeleaf-full-example/pom.xmlplayground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/config/KindeErrorController.javasrc/main/java/com/example/demo/controller/MainController.java
💤 Files with no reviewable changes (2)
- playground/kinde-springboot-starter-example/src/main/java/com/kinde/spring/KindeClientApplication.java
- kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2AutoConfigTest.java
Pulls v2.3.0 + the spring-boot-starter-actuator 3.5.14 Snyk fix + swagger-annotations 2.2.50 + spring-security 6.5.10 from main. Conflict resolution for the 4 pom files (kinde-springboot-core, kinde-springboot-starter, kinde-springboot-starter-example, kinde-springboot-thymeleaf-full-example) is "keep the Spring Boot 4 upgrade": main's explicit Spring Boot 3.5.x / Spring Security 6.5.10 version pins are dropped in favour of inheriting from the SB4 / Security 7 BOMs imported in kinde-springboot-core. The Snyk-driven actuator 3.5.14 pin is superseded by Spring Boot 4.0.6 (actuator 4.0.6 is newer and not affected by the original CVE). Took main's maven-compiler-plugin 3.15.0 bump. Verified: mvn -fae verify - 16/16 modules SUCCESS, 52/52 kinde-springboot-core tests green. Co-authored-by: Cursor <cursoragent@cursor.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
- KindeOAuth2Configurer: use StringUtils.hasText() on getIssuerUri() /
getClientId() instead of !isEmpty() so a partially-configured registration
falls through to the "not configured" log branch instead of NPE'ing.
- TokenUtil.jwtValidator: handle null/empty Jwt.getAudience() explicitly in
the audience validator. A token whose aud claim is absent (not just empty)
now returns OAuth2TokenValidatorResult.failure(INVALID_AUDIENCE) instead
of throwing NPE inside Collections.disjoint.
- TokenUtilTest: regression test for the absent-aud-claim case.
- UserUtil: OIDC decorateUser now matches the registration id with
equalsIgnoreCase("kinde") so it agrees with the OAuth2 overload (was
case-sensitive .equals).
Validated: mvn -pl kinde-springboot/kinde-springboot-core test - 53/53 pass.
…config Cover the previously-uncovered branches that Codecov flagged on PR #248: - KindeOAuth2ResourceServerAutoConfig.restClient()/restTemplate() proxy paths (no proxy / proxy host+port / proxy host+port+credentials). - KindeOAuth2Configurer.init() full DSL flow: drive the Customizer lambdas passed to http.oauth2Login(), http.logout(), and http.oauth2ResourceServer() through Mockito Answers so the lambda bodies (tokenEndpoint, redirectionEndpoint, jwt, opaqueToken, logoutSuccessHandler) execute under JaCoCo. Covers the early-return branches (missing provider/registration, blank issuer/clientId), the happy path, the redirect-uri property branch, the OIDC RP-Initiated logout branch, the JWT resource-server branch, and the opaque-token branch including unsetJwtConfigurer(). Line coverage (kinde-springboot-core): - KindeOAuth2ResourceServerAutoConfig: 4% -> 100% - KindeOAuth2Configurer: 7% -> 88% - KindeOAuth2AutoConfig: 0% -> 100% 67/67 tests pass (mvn -pl kinde-springboot/kinde-springboot-core test).
|
@copilot fix snyk secyrity CI test failure root cause if possible |
Investigated this on 8b4e4f4. GitHub Actions for the PR are green and there isn’t a failing Snyk job/check attached to the PR. The only Snyk-related issue I could trace was the earlier actuator finding already covered by 61ae880 when main was merged; this branch resolves Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
…roper assertions and full DSL coverage
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.java (2)
35-35: ⚡ Quick winRemove debug stdout from test bean setup.
System.out.printlnin test configuration adds CI log noise without test value.Suggested cleanup
public KindeOAuth2ResourceServerAutoConfig kindeOAuth2ResourceServerAutoConfig() { - System.out.println("Hello 3"); KindeOAuth2ResourceServerAutoConfig kindeOAuth2ResourceServerAutoConfig = new KindeOAuth2ResourceServerAutoConfig(); return kindeOAuth2ResourceServerAutoConfig; }As per coding guidelines, "Please focus on: 1. Code quality and best practices".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.java` at line 35, Remove the debugging stdout call from the test setup by deleting the System.out.println("Hello 3") statement found in KindeOAuth2ResourceServerAutoConfigTest; ensure no other leftover System.out/print calls remain in the test configuration or bean setup so CI logs are clean and tests rely only on assertions and logs via the test framework.
66-133: ⚡ Quick winProxy-branch tests are too weak to catch wiring regressions.
All new branch tests only check non-null instances, which will still pass if proxy host/port/credentials are ignored. Please assert observable proxy behavior per branch (e.g., configured proxy/auth on the resulting client objects).
As per coding guidelines, "Please focus on: 4. Test coverage and quality".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.java` around lines 66 - 133, The tests only assert non-null clients but not that proxy settings were applied; update the test methods that call KindeOAuth2ResourceServerAutoConfig.restClient(...) and .restTemplate(...) to verify observable proxy behavior: for RestClient, assert its underlying HTTP transport/config exposes the proxy host/port and (when provided) credentials (inspect the RestClient's HttpClient/connection manager or its proxy selector/Authenticator) and for RestTemplate, unwrap the ClientHttpRequestFactory (or underlying HttpComponentsClientHttpRequestFactory/HttpClient) and assert the Proxy/RoutePlanner and CredentialsProvider contain the expected proxy host, port and username/password derived from KindeOAuth2Properties.Proxy; keep existing test branches (no proxy, host+port, authenticated) but replace the simple assertNotNull checks with assertions against those extracted configuration objects to ensure wiring is correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2AutoConfigTest.java`:
- Around line 118-126: The test currently stubs resourceServerSpec.jwt(...) to
short-circuit so the inner JWT Customizer is never executed; change the jwt(...)
stub to a Mockito Answer that captures the Customizer argument, create a mocked
Jwt spec (e.g., jwtSpec), call customizer.customize(jwtSpec) and then return
resourceServerSpec so the inner lambda runs; update the same pattern for the
other resourceServerSpec.jwt(...) occurrence (the block referenced also at the
later similar stub) and then assert/verify the expected interactions on the
mocked jwtSpec.
---
Nitpick comments:
In
`@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.java`:
- Line 35: Remove the debugging stdout call from the test setup by deleting the
System.out.println("Hello 3") statement found in
KindeOAuth2ResourceServerAutoConfigTest; ensure no other leftover
System.out/print calls remain in the test configuration or bean setup so CI logs
are clean and tests rely only on assertions and logs via the test framework.
- Around line 66-133: The tests only assert non-null clients but not that proxy
settings were applied; update the test methods that call
KindeOAuth2ResourceServerAutoConfig.restClient(...) and .restTemplate(...) to
verify observable proxy behavior: for RestClient, assert its underlying HTTP
transport/config exposes the proxy host/port and (when provided) credentials
(inspect the RestClient's HttpClient/connection manager or its proxy
selector/Authenticator) and for RestTemplate, unwrap the
ClientHttpRequestFactory (or underlying
HttpComponentsClientHttpRequestFactory/HttpClient) and assert the
Proxy/RoutePlanner and CredentialsProvider contain the expected proxy host, port
and username/password derived from KindeOAuth2Properties.Proxy; keep existing
test branches (no proxy, host+port, authenticated) but replace the simple
assertNotNull checks with assertions against those extracted configuration
objects to ensure wiring is correct.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6939deab-d418-4a23-8c78-42eff6bca378
📒 Files selected for processing (6)
kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2AutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2AutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2ResourceServerHttpServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2ServerHttpServerAutoConfigTest.java
dtoxvanilla1991
left a comment
There was a problem hiding this comment.
Good work! Left 4!
- Rename deprecated OAuth2 starters to Spring Boot 4 canonical names
(spring-boot-starter-security-oauth2-{client,resource-server}) across
kinde-springboot-starter and the playground POMs that use them.
- Centralise Jackson management in the root pom (jackson-bom 2.20.0 -> 2.21.2)
and drop redundant per-artifact pins from kinde-springboot-{core,starter}
and the playground POMs.
- Rewrite RestClient / RestTemplate proxy-wiring tests in
KindeOAuth2ResourceServerAutoConfigTest to assert host/port/type via
reflection and verify BasicAuthenticationInterceptor emits the expected
Authorization header (replacing assertNotNull-only checks).
- Convert WebClientUtilTest's User-Agent debug print into an
assertEquals("KINDE", ...) assertion; remove stray System.out.println debug
from kinde-springboot-core auto-config and the kinde-core / springboot
test suites.
- POM hygiene: pin maven-jar-plugin to 3.5.0 (clears the missing-version
warning), dedupe duplicate mockito-core declaration in kinde-springboot-core,
strip empty <build>/<pluginManagement>/<dependencyManagement> blocks and
redundant placeholder/mvnrepository comments across 15+ POMs.
- Refresh the Thymeleaf playground README: correct port (8080), OAuth client
name (kinde, not kinde-provider), Spring Boot version, OAuth2 starter
artifact IDs, and the admin role name.
- Gitignore .env; untrack the six previously committed .env files (local
copies preserved on disk). Add matching .env.example templates documenting
the full KINDE_* env-var surface (per com.kinde.config.KindeParameters).
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@kinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.java`:
- Around line 193-209: The test currently asserts that proxy credentials are
emitted using HttpHeaders.AUTHORIZATION via the helper method
assertBasicAuthInterceptorEmits and BasicAuthenticationInterceptor; change the
test to assert the header HttpHeaders.PROXY_AUTHORIZATION instead (build the
expected "Basic ..." value the same way and check
outgoing.getHeaders().getFirst(HttpHeaders.PROXY_AUTHORIZATION)). Also update
the production code that installs the interceptor (references to
KindeOAuth2ResourceServerAutoConfig where BasicAuthenticationInterceptor or
Authorization header are set) to set the Proxy-Authorization header for proxy
credentials instead of using the origin-server Authorization header or a general
BasicAuthenticationInterceptor for proxy auth.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8c1a7981-57ed-415a-aa0e-71f49e353a8e
⛔ Files ignored due to path filters (14)
.gitignoreis excluded by none and included by nonekinde-core/.envis excluded by none and included by nonekinde-core/.env.exampleis excluded by none and included by nonekinde-j2ee/.envis excluded by none and included by nonekinde-j2ee/.env.exampleis excluded by none and included by nonekinde-management/.envis excluded by none and included by nonekinde-management/.env.exampleis excluded by none and included by noneplayground/kinde-core-example/.envis excluded by none and included by noneplayground/kinde-core-example/.env.exampleis excluded by none and included by noneplayground/kinde-management-example/.envis excluded by none and included by noneplayground/kinde-management-example/.env.exampleis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/.envis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/.env.exampleis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/README.mdis excluded by!**/README.md,!**/*.mdand included by none
📒 Files selected for processing (22)
kinde-core/pom.xmlkinde-core/src/test/java/com/kinde/session/KindeClientCodeSessionImplTest.javakinde-core/src/test/java/com/kinde/token/IDTokenTest.javakinde-j2ee/pom.xmlkinde-management/pom.xmlkinde-report-aggregate/pom.xmlkinde-springboot/kinde-springboot-core/pom.xmlkinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ConfigurerTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2AutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/ReactiveKindeOAuth2ResourceServerAutoConfigTest.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/WebClientUtilTest.javakinde-springboot/kinde-springboot-starter/pom.xmlkinde-springboot/pom.xmlplayground/kinde-accounts-example/pom.xmlplayground/kinde-core-example/pom.xmlplayground/kinde-j2ee-app/pom.xmlplayground/kinde-management-example/pom.xmlplayground/kinde-springboot-pkce-client-example/pom.xmlplayground/kinde-springboot-starter-example/pom.xmlplayground/kinde-springboot-thymeleaf-full-example/pom.xmlpom.xml
💤 Files with no reviewable changes (10)
- playground/kinde-j2ee-app/pom.xml
- kinde-report-aggregate/pom.xml
- playground/kinde-accounts-example/pom.xml
- kinde-j2ee/pom.xml
- kinde-core/src/test/java/com/kinde/session/KindeClientCodeSessionImplTest.java
- kinde-core/src/test/java/com/kinde/token/IDTokenTest.java
- playground/kinde-management-example/pom.xml
- playground/kinde-springboot-starter-example/pom.xml
- playground/kinde-core-example/pom.xml
- kinde-springboot/kinde-springboot-core/pom.xml
✅ Files skipped from review due to trivial changes (2)
- kinde-management/pom.xml
- kinde-springboot/pom.xml
|
Address CI failures and should be solid. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@kinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfig.java`:
- Around line 66-77: The proxy-related code in
KindeOAuth2ResourceServerAutoConfig assumes proxyProperties.getHost(),
getUsername(), and getPassword() are non-null before calling trim(), which can
NPE; update the proxy setup to null-check these fields (or use a null-safe
helper like StringUtils.hasText) before calling trim()/isEmpty(), e.g., ensure
host is non-null && !host.trim().isEmpty() before constructing the Proxy and
ensure username/password are null-checked (or empty-checked via a null-safe
utility) before creating ProxyBasicAuthenticationInterceptor; apply the same
null-safe checks to the other proxy handling block mentioned (lines ~101-112) so
all calls to getHost/getUsername/getPassword are guarded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 84edd18b-44b6-4d93-bce8-4939d1a4726f
⛔ Files ignored due to path filters (4)
playground/kinde-springboot-thymeleaf-full-example/README.mdis excluded by!**/README.md,!**/*.mdand included by noneplayground/kinde-springboot-thymeleaf-full-example/src/main/resources/application.propertiesis excluded by!**/application.propertiesand included by noneplayground/kinde-springboot-thymeleaf-full-example/src/main/resources/static/css/index.cssis excluded by none and included by noneplayground/kinde-springboot-thymeleaf-full-example/src/main/resources/templates/dashboard.htmlis excluded by none and included by none
📒 Files selected for processing (6)
kinde-core/src/main/java/com/kinde/session/KindeClientKindeTokenSessionImpl.javakinde-springboot/kinde-springboot-core/src/main/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfig.javakinde-springboot/kinde-springboot-core/src/test/java/com/kinde/spring/KindeOAuth2ResourceServerAutoConfigTest.javaplayground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/config/SecurityConfig.javaplayground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/controller/KindeController.javaplayground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/service/KindeService.java
💤 Files with no reviewable changes (2)
- playground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/service/KindeService.java
- playground/kinde-springboot-thymeleaf-full-example/src/main/java/com/kinde/oauth/controller/KindeController.java
There was a problem hiding this comment.
Reviewed. The PR delivers a correct, well-tested Spring Boot 4 / Spring Security 7 migration. The proxy authentication implementation is particularly well-executed: ProxyBasicAuthenticationInterceptor correctly targets Proxy-Authorization, the null-credential path is guarded with StringUtils.hasText(), and the test suite pins both the positive and the confidentiality-leak side of the assertion. Safe to merge. Needs Snyk CI resolution.
Summary
Upgrades
kinde-springboot-starterandkinde-springboot-coreto Spring Boot 4.0.6, Spring Security 7.0.5 and the Java 25 toolchain (Java 17+ runtime baseline).Beyond the framework bump, live end-to-end testing against a real Kinde tenant uncovered five real SDK bugs that prevented every Kinde-on-Spring-Boot user from getting a working setup. All five are fixed here.
Bugs found and fixed
Missing OAuth2 starters in
kinde-springboot-starter. Spring Boot 4 split OAuth2 auto-configuration out ofspring-boot-autoconfigureinto dedicated starters; the starter pom did not follow.Symptom previously:
NoClassDefFoundErrorforOAuth2ClientPropertieson startup.Token-exchange
RestClientwas missing required converters. The customRestClientthat talks to Kinde's/tokenendpoint did not registerFormHttpMessageConverter,OAuth2AccessTokenResponseHttpMessageConverterorOAuth2ErrorResponseErrorHandler— all of which Spring Security 7 now requires.Symptom previously:
NullPointerExceptionduring the OIDC login callback, browser ends up in a redirect loop.JWT audience validator rejected every default Kinde token. The validator was hardcoded with the Okta sample default
"api://default"and always enforced. Real Kinde access tokens carry an emptyaudarray until you explicitly configure an API resource on the dashboard. Audience checking is now opt-in (enforced only whenkinde.oauth2.audienceis set).Symptom previously:
401 "This aud claim is not equal to the configured audience"on every Bearer-token-protected endpoint.RP-Initiated logout never wired up. The
OidcClientInitiatedLogoutSuccessHandlerbean was conditional on a property namedokta.oauth2.post-logout-redirect-uri— a leftover from the Okta fork this code descends from. Same typo existed in the reactive variant. Both conditionals are nowkinde.oauth2.post-logout-redirect-uri, whichKindeOAuth2Configurerwires into everyHttpSecurityviaMETA-INF/spring.factories.Spring Security 6 → 7 source incompatibilities in tests. Removed and renamed APIs updated. 5 new
TokenUtilTestcases added covering the audience-opt-in behaviour and a wrong-issuer regression.Test plan
mvn -fae verifyfrom repo root — 16/16 modules SUCCESSmvn -N testinkinde-springboot-core— 52/52 tests pass (incl. 5 new ones)oauth2Loginend-to-end against live Kinde tenant — login round-trip worksoauth2Loginwith PKCE force-enabled — login round-trip works in WebFlux app@PreAuthorize, dashboard, account portal) — all routes workGET /api/mewith a real Bearer token returns 200 with bothSCOPE_*and Kindepermissionsmerged into Spring authorities/registrationcorrectly propagatesprompt=createto the Kinde authorize URL?invitation_code=...correctly propagatesinvitation_code+is_invitation=trueto the Kinde authorize URLPOST /logout→ 302 tohttps://<tenant>.kinde.com/logout?id_token_hint=…&post_logout_redirect_uri=…→ 302 back, fully logged outReviewer notes
Behaviour changes downstream users should be aware of
These are documented in
MIGRATION.md:kinde.oauth2.audienceis now opt-in. If you previously relied on the implicit"api://default"default, set the property explicitly. (Highly unlikely to affect anyone — the previous default rejected every valid Kinde token.)okta.oauth2.post-logout-redirect-uri→kinde.oauth2.post-logout-redirect-uri. Same rename for the reactive variant.Playground changes
kinde-springboot-starter-examplegained a small Bearer-onlySecurityFilterChainplusApiControllerandDebugControllerso contributors can verify the resource-server path in seconds with acurl.DebugControlleris gated behindoauth2Loginand clearly not for production.kinde-springboot-pkce-client-exampleyaml renamed the registration id frompkcetokindeso the default callback/login/oauth2/code/kindematches the redirect URI registered on the Kinde dashboard.kinde-springboot-thymeleaf-full-exampleapplication.propertieshad hardcoded tenant URLs (koman.kinde.com) — now parameterised via${KINDE_PREFIX}, matching the rest of the file..envexample refreshed with placeholder values for new contributors.Other cleanup included in this PR (separate commits, no behaviour change)
kinde-report-aggregate/README.mdexplaining what that previously-mysterious module does (JaCoCo coverage aggregator).src/main/java/com/example/demo/controller/MainController.javaat repo root (a Spring Initializr leftover, never referenced).PropertySourcename.Commits
Checklist
🛟 If you need help, consider asking for advice over in the Kinde community.
Summary by CodeRabbit
New Features
Improvements
Tests
Chores