Skip to content

feat: Add RFC 8414 OAuth 2.0 Authorization Server Metadata endpoint#1665

Open
zacharypodbela wants to merge 2 commits intodjango-oauth:masterfrom
ForaTravel:rfc-8414-oauth-server-metadata
Open

feat: Add RFC 8414 OAuth 2.0 Authorization Server Metadata endpoint#1665
zacharypodbela wants to merge 2 commits intodjango-oauth:masterfrom
ForaTravel:rfc-8414-oauth-server-metadata

Conversation

@zacharypodbela
Copy link
Copy Markdown

Summary

Implements the /.well-known/oauth-authorization-server discovery endpoint per RFC 8414 — OAuth 2.0 Authorization Server Metadata.

Closes #1099

Changes

  • New oauth2_provider/views/metadata.py — contains ServerMetadataViewMixin (shared URL-building logic for discovery views) and OAuthServerMetadataView (the RFC 8414 endpoint). The view is available regardless of whether OIDC is enabled and has no OIDCOnlyMixin dependency.
  • Refactored ConnectDiscoveryInfoView — now inherits ServerMetadataViewMixin, eliminating the duplicated if/else URL-building logic that previously existed for the request-relative vs OIDC_ISS_ENDPOINT-anchored cases.
  • New settings with sensible defaults:
    • OAUTH2_RESPONSE_TYPES_SUPPORTED
    • OAUTH2_GRANT_TYPES_SUPPORTED
    • OAUTH2_TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTED
  • New oauth2_metadata_issuer() helper on OAuth2ProviderSettings, mirroring the existing oidc_issuer().
  • New URL oauth-server-metadata registered in base_urlpatterns.
  • Tests covering: full response structure, request-derived issuer (no OIDC_ISS_ENDPOINT), jwks_uri conditional on RSA key presence, CORS header, and availability when OIDC is disabled.

Relationship to OIDC discovery

RFC 8414 is the OAuth 2.0 equivalent of OpenID Connect discovery. The key differences from ConnectDiscoveryInfoView:

/.well-known/openid-configuration /.well-known/oauth-authorization-server
Spec OpenID Connect Discovery 1.0 RFC 8414
Requires OIDC Yes No
userinfo_endpoint Yes No
jwks_uri Always Only if RSA key configured
grant_types_supported No Yes
revocation_endpoint No Yes
introspection_endpoint No Yes

@zacharypodbela
Copy link
Copy Markdown
Author

@dopry could I get a review on this?

@dopry dopry force-pushed the rfc-8414-oauth-server-metadata branch from b6b1c88 to d5108c7 Compare March 12, 2026 19:50
@dopry dopry requested a review from Copilot March 12, 2026 19:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an RFC 8414-compliant OAuth 2.0 Authorization Server Metadata discovery endpoint and refactors existing OIDC discovery code to reuse shared URL-building logic.

Changes:

  • Added /.well-known/oauth-authorization-server endpoint with RFC 8414 metadata response and CORS header.
  • Introduced ServerMetadataViewMixin and refactored ConnectDiscoveryInfoView to remove duplicated endpoint URL-building logic.
  • Added new settings defaults + documentation, and tests for endpoint behavior (issuer derivation, JWKS conditional, CORS, OIDC disabled).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_oidc_views.py Adds tests validating RFC 8414 metadata response shape and key conditionals.
oauth2_provider/views/oidc.py Refactors OIDC discovery to reuse shared endpoint URL builder.
oauth2_provider/views/metadata.py Implements the RFC 8414 metadata endpoint + shared URL-building mixin.
oauth2_provider/views/init.py Exposes the new metadata view for URL registration.
oauth2_provider/urls.py Registers the /.well-known/oauth-authorization-server route.
oauth2_provider/settings.py Adds OAuth2 metadata settings and an issuer helper method.
docs/settings.rst Documents new settings related to the metadata endpoint.
docs/oauth2_server_metadata.rst Adds user-facing docs for the RFC 8414 endpoint.
docs/index.rst Adds the new docs page to the documentation index.
CHANGELOG.md Notes the new endpoint in the unreleased changelog.

Comment on lines +317 to +318
abs_url = request.build_absolute_uri(reverse("oauth2_provider:oauth-server-metadata"))
return abs_url[: -len("/.well-known/oauth-authorization-server")]
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The issuer calculation relies on a hard-coded path suffix (\"/.well-known/oauth-authorization-server\"). This will silently break if the URL pattern changes. Prefer deriving the suffix from reverse(\"oauth2_provider:oauth-server-metadata\") (or using a removesuffix()-style approach with the reversed path) so this stays correct if the route is modified.

Suggested change
abs_url = request.build_absolute_uri(reverse("oauth2_provider:oauth-server-metadata"))
return abs_url[: -len("/.well-known/oauth-authorization-server")]
metadata_path = reverse("oauth2_provider:oauth-server-metadata")
abs_url = request.build_absolute_uri(metadata_path)
if abs_url.endswith(metadata_path):
return abs_url[: -len(metadata_path)]
return abs_url

Copilot uses AI. Check for mistakes.
"introspection_endpoint": self._get_endpoint_url(request, "introspect"),
"response_types_supported": oauth2_settings.OAUTH2_RESPONSE_TYPES_SUPPORTED,
"grant_types_supported": oauth2_settings.OAUTH2_GRANT_TYPES_SUPPORTED,
"scopes_supported": list(scopes.get_available_scopes()),
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

For metadata documents, producing deterministic output is useful (and avoids flaky tests/clients doing strict comparisons). scopes_supported currently preserves whatever ordering the scopes backend returns, which may vary by backend implementation. Consider normalizing to a stable order (e.g., sorting) before returning.

Suggested change
"scopes_supported": list(scopes.get_available_scopes()),
"scopes_supported": sorted(scopes.get_available_scopes()),

Copilot uses AI. Check for mistakes.
Comment on lines +809 to +811
response = self.client.get(reverse("oauth2_provider:oauth-server-metadata"))
self.assertEqual(response.status_code, 200)
assert response.json() == expected_response
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This test asserts full JSON equality, which can become brittle if any list fields are legitimately reordered (e.g., scopes_supported, code_challenge_methods_supported). If ordering is not part of the contract, consider asserting per-field presence/values (order-insensitive where appropriate), or sorting the corresponding fields in the response before comparing.

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

zacharypodbela and others added 2 commits March 12, 2026 22:45
Implements the /.well-known/oauth-authorization-server discovery endpoint
per RFC 8414. Unlike the existing OIDC discovery endpoint, this is available
regardless of whether OIDC is enabled.

- Add OAuthServerMetadataView and ServerMetadataViewMixin in new metadata.py
- Refactor ConnectDiscoveryInfoView to use ServerMetadataViewMixin, removing
  duplicated URL-building logic
- Add OAUTH2_RESPONSE_TYPES_SUPPORTED, OAUTH2_GRANT_TYPES_SUPPORTED, and
  OAUTH2_TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTED settings with defaults
- Add oauth2_metadata_issuer() helper to OAuth2ProviderSettings
- Register endpoint in base_urlpatterns as oauth-server-metadata

Closes django-oauth#1099

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add oauth2_server_metadata.rst with endpoint description and example response
- Link from index.rst toctree after oidc
- Document OAUTH2_RESPONSE_TYPES_SUPPORTED, OAUTH2_GRANT_TYPES_SUPPORTED,
  and OAUTH2_TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTED in settings.rst

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dopry dopry force-pushed the rfc-8414-oauth-server-metadata branch from d5108c7 to 2a42baa Compare March 13, 2026 02:46
@dopry
Copy link
Copy Markdown
Member

dopry commented Mar 13, 2026

@zacharypodbela can you review the copilot comments and address them?

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.

RFC 8414 .well-known/oauth-authorization-server metadata

3 participants