Skip to content

Commit e038f42

Browse files
authored
Fix/wellknown openid configuration no trailing slash (#1364)
* chore: tests showing configuration error * fix: Connect Discovery Endpoint redirects
1 parent 862cb7a commit e038f42

File tree

5 files changed

+38
-8
lines changed

5 files changed

+38
-8
lines changed

docs/oidc.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ the URLs accordingly.
407407
ConnectDiscoveryInfoView
408408
~~~~~~~~~~~~~~~~~~~~~~~~
409409

410-
Available at ``/o/.well-known/openid-configuration/``, this view provides auto
410+
Available at ``/o/.well-known/openid-configuration``, this view provides auto
411411
discovery information to OIDC clients, telling them the JWT issuer to use, the
412412
location of the JWKs to verify JWTs with, the token and userinfo endpoints to
413413
query, and other details.

docs/settings.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ Default: ``""``
366366
The URL of the issuer that is used in the ID token JWT and advertised in the
367367
OIDC discovery metadata. Clients use this location to retrieve the OIDC
368368
discovery metadata from ``OIDC_ISS_ENDPOINT`` +
369-
``/.well-known/openid-configuration/``.
369+
``/.well-known/openid-configuration``.
370370

371371
If unset, the default location is used, eg if ``django-oauth-toolkit`` is
372372
mounted at ``/o``, it will be ``<server-address>/o``.

oauth2_provider/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def oidc_issuer(self, request):
295295
else:
296296
raise TypeError("request must be a django or oauthlib request: got %r" % request)
297297
abs_url = django_request.build_absolute_uri(reverse("oauth2_provider:oidc-connect-discovery-info"))
298-
return abs_url[: -len("/.well-known/openid-configuration/")]
298+
return abs_url[: -len("/.well-known/openid-configuration")]
299299

300300

301301
oauth2_settings = OAuth2ProviderSettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS, MANDATORY)

oauth2_provider/urls.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@
3131
]
3232

3333
oidc_urlpatterns = [
34+
# .well-known/openid-configuration/ is deprecated
35+
# https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
36+
# does not specify a trailing slash
37+
# Support for trailing slash should shall be removed in a future release.
3438
re_path(
35-
r"^\.well-known/openid-configuration/$",
39+
r"^\.well-known/openid-configuration/?$",
3640
views.ConnectDiscoveryInfoView.as_view(),
3741
name="oidc-connect-discovery-info",
3842
),

tests/test_oidc_views.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,37 @@ def test_get_connect_discovery_info(self):
5050
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
5151
"claims_supported": ["sub"],
5252
}
53-
response = self.client.get(reverse("oauth2_provider:oidc-connect-discovery-info"))
53+
response = self.client.get("/o/.well-known/openid-configuration")
54+
self.assertEqual(response.status_code, 200)
55+
assert response.json() == expected_response
56+
57+
def test_get_connect_discovery_info_deprecated(self):
58+
expected_response = {
59+
"issuer": "http://localhost/o",
60+
"authorization_endpoint": "http://localhost/o/authorize/",
61+
"token_endpoint": "http://localhost/o/token/",
62+
"userinfo_endpoint": "http://localhost/o/userinfo/",
63+
"jwks_uri": "http://localhost/o/.well-known/jwks.json",
64+
"scopes_supported": ["read", "write", "openid"],
65+
"response_types_supported": [
66+
"code",
67+
"token",
68+
"id_token",
69+
"id_token token",
70+
"code token",
71+
"code id_token",
72+
"code id_token token",
73+
],
74+
"subject_types_supported": ["public"],
75+
"id_token_signing_alg_values_supported": ["RS256", "HS256"],
76+
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
77+
"claims_supported": ["sub"],
78+
}
79+
response = self.client.get("/o/.well-known/openid-configuration/")
5480
self.assertEqual(response.status_code, 200)
5581
assert response.json() == expected_response
5682

57-
def expect_json_response_with_rp(self, base):
83+
def expect_json_response_with_rp_logout(self, base):
5884
expected_response = {
5985
"issuer": f"{base}",
6086
"authorization_endpoint": f"{base}/authorize/",
@@ -83,7 +109,7 @@ def expect_json_response_with_rp(self, base):
83109

84110
def test_get_connect_discovery_info_with_rp_logout(self):
85111
self.oauth2_settings.OIDC_RP_INITIATED_LOGOUT_ENABLED = True
86-
self.expect_json_response_with_rp(self.oauth2_settings.OIDC_ISS_ENDPOINT)
112+
self.expect_json_response_with_rp_logout(self.oauth2_settings.OIDC_ISS_ENDPOINT)
87113

88114
def test_get_connect_discovery_info_without_issuer_url(self):
89115
self.oauth2_settings.OIDC_ISS_ENDPOINT = None
@@ -117,7 +143,7 @@ def test_get_connect_discovery_info_without_issuer_url_with_rp_logout(self):
117143
self.oauth2_settings.OIDC_RP_INITIATED_LOGOUT_ENABLED = True
118144
self.oauth2_settings.OIDC_ISS_ENDPOINT = None
119145
self.oauth2_settings.OIDC_USERINFO_ENDPOINT = None
120-
self.expect_json_response_with_rp("http://testserver/o")
146+
self.expect_json_response_with_rp_logout("http://testserver/o")
121147

122148
def test_get_connect_discovery_info_without_rsa_key(self):
123149
self.oauth2_settings.OIDC_RSA_PRIVATE_KEY = None

0 commit comments

Comments
 (0)