feat(kotlin-client): support dynamic auth credentials for okhttp client (#23835)#23836
feat(kotlin-client): support dynamic auth credentials for okhttp client (#23835)#23836manujell73 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
8 issues found across 61 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/others/kotlin-jvm-okhttp-path-comments/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt">
<violation number="1" location="samples/client/others/kotlin-jvm-okhttp-path-comments/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt:123">
P1: Dynamic auth providers are not injectable: `accessTokenProvider` and `userCredentialsProvider` are `val` (final) instance properties that cannot be overridden or reassigned, and are not constructor parameters. Generated-client callers cannot supply custom token sources, so the provider always falls back to the static companion-object fields and the dynamic-auth feature is effectively inert.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/kotlin-client/api_doc.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-client/api_doc.mustache:88">
P1: Dynamic auth docs configure provider on a throwaway instance, causing silent auth failure when followed</violation>
</file>
<file name="samples/client/echo_api/kotlin-jvm-spring-3-webclient/docs/AuthApi.md">
<violation number="1" location="samples/client/echo_api/kotlin-jvm-spring-3-webclient/docs/AuthApi.md:55">
P2: Webclient sample docs advertise dynamic auth provider APIs that are not implemented in the webclient generated code</violation>
</file>
<file name="samples/client/petstore/kotlin-jackson/docs/PetApi.md">
<violation number="1" location="samples/client/petstore/kotlin-jackson/docs/PetApi.md:60">
P1: Dynamic auth documentation configures accessTokenProvider on a newly created, discarded PetApi instance rather than the apiInstance used in the preceding request example. Because accessTokenProvider is an instance property in the generated ApiClient base class, this pattern will not apply credentials to the actual request instance, causing auth headers to be missing.</violation>
</file>
<file name="samples/client/petstore/kotlin-jvm-ktor-gson/docs/FakeApi.md">
<violation number="1" location="samples/client/petstore/kotlin-jvm-ktor-gson/docs/FakeApi.md:105">
P2: Ktor sample docs advertise `accessTokenProvider` which does not exist in the generated Ktor client code, causing a generator/docs mismatch.</violation>
</file>
<file name="samples/client/others/kotlin-jvm-okhttp-non-ascii-headers/docs/PetApi.md">
<violation number="1" location="samples/client/others/kotlin-jvm-okhttp-non-ascii-headers/docs/PetApi.md:63">
P1: Dynamic auth documentation configures `accessTokenProvider` on a throwaway `PetApi()` instance instead of the `apiInstance` used in the request example. Since `accessTokenProvider` is an instance property of `ApiClient`, users following these docs will not have their dynamic credentials applied to actual requests.</violation>
</file>
<file name="samples/client/petstore/kotlin-jvm-vertx-moshi/docs/PetApi.md">
<violation number="1" location="samples/client/petstore/kotlin-jvm-vertx-moshi/docs/PetApi.md:63">
P1: Cross-generator documentation mismatch: `kotlin-jvm-vertx-moshi` docs now reference `accessTokenProvider`, which is only implemented in the `jvm-okhttp` library template. The shared `api_doc.mustache` was updated for okhttp dynamic credentials, but vertx-moshi's generated `ApiClient.kt` does not have this property, so the documented example code will not compile.</violation>
</file>
<file name="samples/client/petstore/kotlin-allOf-discriminator-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt">
<violation number="1" location="samples/client/petstore/kotlin-allOf-discriminator-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt:123">
P2: Dynamic auth providers are hardcoded `val` with no configuration path, making the advertised per-instance provider support unusable. The `userCredentialsProvider` and `accessTokenProvider` default to reading static companion fields and cannot be overridden or injected.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| } | ||
|
|
||
| val userCredentialsProvider: () -> Pair<String?, String?> = { username to password } | ||
| val accessTokenProvider: () -> String? = { accessToken } |
There was a problem hiding this comment.
P1: Dynamic auth providers are not injectable: accessTokenProvider and userCredentialsProvider are val (final) instance properties that cannot be overridden or reassigned, and are not constructor parameters. Generated-client callers cannot supply custom token sources, so the provider always falls back to the static companion-object fields and the dynamic-auth feature is effectively inert.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/others/kotlin-jvm-okhttp-path-comments/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt, line 123:
<comment>Dynamic auth providers are not injectable: `accessTokenProvider` and `userCredentialsProvider` are `val` (final) instance properties that cannot be overridden or reassigned, and are not constructor parameters. Generated-client callers cannot supply custom token sources, so the provider always falls back to the static companion-object fields and the dynamic-auth feature is effectively inert.</comment>
<file context>
@@ -119,6 +119,9 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
}
+ val userCredentialsProvider: () -> Pair<String?, String?> = { username to password }
+ val accessTokenProvider: () -> String? = { accessToken }
+
/**
</file context>
| ``` | ||
| Configure {{name}} dynamically: | ||
| ```kotlin | ||
| {{{classname}}}().accessTokenProvider = { "" } |
There was a problem hiding this comment.
P1: Dynamic auth docs configure provider on a throwaway instance, causing silent auth failure when followed
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/kotlin-client/api_doc.mustache, line 88:
<comment>Dynamic auth docs configure provider on a throwaway instance, causing silent auth failure when followed</comment>
<file context>
@@ -68,18 +68,36 @@ Configure {{name}}:
+```
+Configure {{name}} dynamically:
+```kotlin
+{{{classname}}}().accessTokenProvider = { "" }
+```
{{/isBasicBearer}}
</file context>
| ``` | ||
| Configure petstore_auth dynamically: | ||
| ```kotlin | ||
| PetApi().accessTokenProvider = { "" } |
There was a problem hiding this comment.
P1: Dynamic auth documentation configures accessTokenProvider on a newly created, discarded PetApi instance rather than the apiInstance used in the preceding request example. Because accessTokenProvider is an instance property in the generated ApiClient base class, this pattern will not apply credentials to the actual request instance, causing auth headers to be missing.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-jackson/docs/PetApi.md, line 60:
<comment>Dynamic auth documentation configures accessTokenProvider on a newly created, discarded PetApi instance rather than the apiInstance used in the preceding request example. Because accessTokenProvider is an instance property in the generated ApiClient base class, this pattern will not apply credentials to the actual request instance, causing auth headers to be missing.</comment>
<file context>
@@ -51,8 +51,14 @@ null (empty response body)
+```
+Configure petstore_auth dynamically:
+```kotlin
+PetApi().accessTokenProvider = { "" }
+```
</file context>
| ``` | ||
| Configure petstore_auth dynamically: | ||
| ```kotlin | ||
| PetApi().accessTokenProvider = { "" } |
There was a problem hiding this comment.
P1: Dynamic auth documentation configures accessTokenProvider on a throwaway PetApi() instance instead of the apiInstance used in the request example. Since accessTokenProvider is an instance property of ApiClient, users following these docs will not have their dynamic credentials applied to actual requests.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/others/kotlin-jvm-okhttp-non-ascii-headers/docs/PetApi.md, line 63:
<comment>Dynamic auth documentation configures `accessTokenProvider` on a throwaway `PetApi()` instance instead of the `apiInstance` used in the request example. Since `accessTokenProvider` is an instance property of `ApiClient`, users following these docs will not have their dynamic credentials applied to actual requests.</comment>
<file context>
@@ -54,8 +54,14 @@ try {
+```
+Configure petstore_auth dynamically:
+```kotlin
+PetApi().accessTokenProvider = { "" }
+```
</file context>
| PetApi().accessTokenProvider = { "" } | |
| apiInstance.accessTokenProvider = { "" } |
| ``` | ||
| Configure petstore_auth dynamically: | ||
| ```kotlin | ||
| PetApi().accessTokenProvider = { "" } |
There was a problem hiding this comment.
P1: Cross-generator documentation mismatch: kotlin-jvm-vertx-moshi docs now reference accessTokenProvider, which is only implemented in the jvm-okhttp library template. The shared api_doc.mustache was updated for okhttp dynamic credentials, but vertx-moshi's generated ApiClient.kt does not have this property, so the documented example code will not compile.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-jvm-vertx-moshi/docs/PetApi.md, line 63:
<comment>Cross-generator documentation mismatch: `kotlin-jvm-vertx-moshi` docs now reference `accessTokenProvider`, which is only implemented in the `jvm-okhttp` library template. The shared `api_doc.mustache` was updated for okhttp dynamic credentials, but vertx-moshi's generated `ApiClient.kt` does not have this property, so the documented example code will not compile.</comment>
<file context>
@@ -54,8 +54,14 @@ try {
+```
+Configure petstore_auth dynamically:
+```kotlin
+PetApi().accessTokenProvider = { "" }
+```
</file context>
| ``` | ||
| Configure http_auth dynamically: | ||
| ```kotlin | ||
| AuthApi().userCredentialProvider = { "user" to "pass" } |
There was a problem hiding this comment.
P2: Webclient sample docs advertise dynamic auth provider APIs that are not implemented in the webclient generated code
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/kotlin-jvm-spring-3-webclient/docs/AuthApi.md, line 55:
<comment>Webclient sample docs advertise dynamic auth provider APIs that are not implemented in the webclient generated code</comment>
<file context>
@@ -45,9 +45,15 @@ This endpoint does not need any parameter.
+```
+Configure http_auth dynamically:
+```kotlin
+AuthApi().userCredentialProvider = { "user" to "pass" }
+```
</file context>
| ``` | ||
| Configure petstore_auth dynamically: | ||
| ```kotlin | ||
| FakeApi().accessTokenProvider = { "" } |
There was a problem hiding this comment.
P2: Ktor sample docs advertise accessTokenProvider which does not exist in the generated Ktor client code, causing a generator/docs mismatch.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-jvm-ktor-gson/docs/FakeApi.md, line 105:
<comment>Ktor sample docs advertise `accessTokenProvider` which does not exist in the generated Ktor client code, causing a generator/docs mismatch.</comment>
<file context>
@@ -96,8 +96,14 @@ null (empty response body)
+```
+Configure petstore_auth dynamically:
+```kotlin
+FakeApi().accessTokenProvider = { "" }
+```
</file context>
| val builder: OkHttpClient.Builder = OkHttpClient.Builder() | ||
| } | ||
|
|
||
| val userCredentialsProvider: () -> Pair<String?, String?> = { username to password } |
There was a problem hiding this comment.
P2: Dynamic auth providers are hardcoded val with no configuration path, making the advertised per-instance provider support unusable. The userCredentialsProvider and accessTokenProvider default to reading static companion fields and cannot be overridden or injected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/kotlin-allOf-discriminator-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt, line 123:
<comment>Dynamic auth providers are hardcoded `val` with no configuration path, making the advertised per-instance provider support unusable. The `userCredentialsProvider` and `accessTokenProvider` default to reading static companion fields and cannot be overridden or injected.</comment>
<file context>
@@ -120,6 +120,9 @@ open class ApiClient(val baseUrl: String, val client: Call.Factory = defaultClie
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
}
+ val userCredentialsProvider: () -> Pair<String?, String?> = { username to password }
+ val accessTokenProvider: () -> String? = { accessToken }
+
</file context>
resolves #23835
This change adds dynamic credential/token provider support to Kotlin jvm-okhttp clients so auth values can be resolved at request time (instead of only using static ApiClient fields).
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
master(upcoming7.x.0minor release - breaking changes with fallbacks),8.0.x(breaking changes without fallbacks)"fixes #123"present in the PR description)Kotlin comittee:
@karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) @stefankoppier (2022/06) @e5l (2024/10) @dennisameling (2026/02)
Summary by cubic
Adds dynamic auth providers to Kotlin JVM
okhttpclients so credentials/tokens are resolved per request. This enables rotating tokens and multi-tenant auth without rebuilding the client.userCredentialsProviderandaccessTokenProvidercallbacks onApiClientfor JVMokhttpclients; invoked at request time to set theAuthorizationheader when missing.Written for commit 22fe45d. Summary will update on new commits. Review in cubic