Skip to content

Add OpenID Connect discovery metadata#5632

Open
Pantus Oleh (zibet27) wants to merge 4 commits into
zibet27/http-auth-algorithmsfrom
zibet27/oidc-discovery
Open

Add OpenID Connect discovery metadata#5632
Pantus Oleh (zibet27) wants to merge 4 commits into
zibet27/http-auth-algorithmsfrom
zibet27/oidc-discovery

Conversation

@zibet27

@zibet27 Pantus Oleh (zibet27) commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Subsystem
Server Auth

Motivation
KTOR-5001 Add OpenID Connect (OIDC) support on client and server

Solution
Adds the initial ktor-server-auth-openid module with OpenID Connect Discovery support.

  • OpenIdProviderMetadata for decoding /.well-known/openid-configuration
  • HttpClient.fetchOpenIdMetadata(issuer) helper
  • DiscoveryException for fetch/validation failures
  • tests for successful discovery, optional fields, required endpoint validation, and HTTP errors

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • main
  • release/*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 21652570-7545-47c5-862d-6c3113b4b9cc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces OpenID Connect discovery support to Ktor by adding a new ktor-server-auth-openid plugin module. The module provides a serializable metadata model, an HTTP client extension to fetch and validate provider metadata from the .well-known/openid-configuration endpoint, and comprehensive test coverage for both happy-path and error scenarios.

Changes

OpenID Connect Discovery Module

Layer / File(s) Summary
Module setup and configuration
settings.gradle.kts, ktor-server/ktor-server-plugins/ktor-server-auth-openid/build.gradle.kts, gradle/artifacts/publishJvmAndCommonPublications.txt
Registers the ktor-server-auth-openid subproject, configures Gradle with server plugin and serialization support, and publishes JVM and common module artifacts including .jar, sources.jar, and javadoc.jar.
OpenID metadata model
ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/src/io/ktor/server/auth/openid/OpenIdProviderMetadata.kt
Defines OpenIdProviderMetadata as a serializable data class with @SerialName mappings for OpenID discovery document fields, supporting required endpoints (issuer, authorizationEndpoint, tokenEndpoint, jwksUri) and optional capabilities (algorithms, response types, supported scopes).
Discovery exception and fetch logic
ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/src/io/ktor/server/auth/openid/OpenIdProviderMetadata.kt
Introduces DiscoveryException for failure handling and HttpClient.fetchOpenIdMetadata(issuer) extension that fetches the discovery document, deserializes it, rethrows cancellations, wraps other errors, and validates required endpoint fields are non-blank.
Public API surface
ktor-server/ktor-server-plugins/ktor-server-auth-openid/api/ktor-server-auth-openid.api
Documents the public API for DiscoveryException, OpenIdProviderMetadata class and constructor, serialization support, and the fetchOpenIdMetadata coroutine function.
Test coverage
ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/test/io/ktor/server/auth/openid/FetchOpenIdProviderMetadataTest.kt
Tests discovery with baseline required fields, optional specification fields, all-null optional fields, and validation failures for missing jwksUri, missing authorizationEndpoint, missing tokenEndpoint, and HTTP errors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Suggested labels

👍 ship!


Suggested reviewers

  • bjhham
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding OpenID Connect discovery metadata support to the Ktor framework.
Description check ✅ Passed The description follows the template with all required sections (Subsystem, Motivation, Solution) properly filled out with specific details about the implementation and testing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch zibet27/oidc-discovery

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@zibet27

Copy link
Copy Markdown
Collaborator Author

CodeRabbit (@coderabbitai) review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/test/io/ktor/server/auth/openid/FetchOpenIdProviderMetadataTest.kt (1)

49-229: ⚡ Quick win

Use descriptive backticked test names for readability.

Please rename these tests to backticked descriptions to match repository test style.

As per coding guidelines: **/*Test.{kt,kts}: Prefer descriptive test names in backticks: describe what is being tested.

🤖 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
`@ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/test/io/ktor/server/auth/openid/FetchOpenIdProviderMetadataTest.kt`
around lines 49 - 229, The test functions (e.g., testFetchOpenIdConfiguration,
testFetchOpenIdConfigurationNewSpecFields,
testFetchOpenIdConfigurationAllOptionalFieldsNull,
testFetchOpenIdConfigurationMissingJwksUri,
testFetchOpenIdConfigurationMissingAuthorizationEndpoint,
testFetchOpenIdConfigurationMissingTokenEndpoint,
testFetchOpenIdConfigurationHttpError) should be renamed to descriptive
backticked test names to match project style; update each function declaration
from fun testXxx() to fun `describe what is being tested`() while leaving the
`@Test` annotation, testApplication block, and the test bodies unchanged so only
the identifier becomes a human-readable backticked string (for example: fun
`fetches OpenID configuration and parses required fields`() = testApplication {
... }).
🤖 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
`@ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/src/io/ktor/server/auth/openid/OpenIdProviderMetadata.kt`:
- Around line 218-223: In fetchOpenIdMetadata, validate the issuer argument
up-front using require(!issuer.isBlank()) to fail fast before any URL building
or network calls; add an actionable error message that includes the problematic
issuer value (e.g., "issuer must not be blank: '$issuer'") so callers get clear
context; perform this check at the start of the suspend function before using
url.takeFrom or calling get.
- Around line 227-231: Replace the broad "catch (e: Throwable)" in the
OpenIdProviderMetadata.kt discovery code with "catch (e: Exception)" so fatal
JVM errors (e.g., OutOfMemoryError, StackOverflowError) are not accidentally
swallowed; keep the existing separate "catch (e: CancellationException) { throw
e }" branch and continue to wrap non-fatal exceptions in the DiscoveryException
thrown when fetching OpenID configuration from the issuer.

---

Nitpick comments:
In
`@ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/test/io/ktor/server/auth/openid/FetchOpenIdProviderMetadataTest.kt`:
- Around line 49-229: The test functions (e.g., testFetchOpenIdConfiguration,
testFetchOpenIdConfigurationNewSpecFields,
testFetchOpenIdConfigurationAllOptionalFieldsNull,
testFetchOpenIdConfigurationMissingJwksUri,
testFetchOpenIdConfigurationMissingAuthorizationEndpoint,
testFetchOpenIdConfigurationMissingTokenEndpoint,
testFetchOpenIdConfigurationHttpError) should be renamed to descriptive
backticked test names to match project style; update each function declaration
from fun testXxx() to fun `describe what is being tested`() while leaving the
`@Test` annotation, testApplication block, and the test bodies unchanged so only
the identifier becomes a human-readable backticked string (for example: fun
`fetches OpenID configuration and parses required fields`() = testApplication {
... }).
🪄 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: 8cd7fd3a-66b1-4486-84e0-5fdd58fda305

📥 Commits

Reviewing files that changed from the base of the PR and between 645f326 and 3d050f8.

📒 Files selected for processing (6)
  • gradle/artifacts/publishJvmAndCommonPublications.txt
  • ktor-server/ktor-server-plugins/ktor-server-auth-openid/api/ktor-server-auth-openid.api
  • ktor-server/ktor-server-plugins/ktor-server-auth-openid/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/src/io/ktor/server/auth/openid/OpenIdProviderMetadata.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-openid/jvm/test/io/ktor/server/auth/openid/FetchOpenIdProviderMetadataTest.kt
  • settings.gradle.kts

@bjhham Bruce Hamilton (bjhham) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍

Added a few trivial comments.

}.body<OpenIdProviderMetadata>()
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused why we wrap exceptions like this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To unify exceptions
Afaik, it's a common pattern on JVM, though I'm not a huge fan of it
Bruce Hamilton (@bjhham), Osip Fatkullin (@osipxd) wdyt?

@nomisRev Simon Vergauwen (nomisRev) Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afaik, it's a common pattern on JVM

It's also consider a controversial pattern by many, I am personally also not a fan of it.

Here is find it especially confusing since we're turning our own exceptions from Ktor HttpClient into different errors, and the actual cause will get buried in a long stack trace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants