Skip to content

Commit

Permalink
Fix/wellknown openid configuration no trailing slash (#1364)
Browse files Browse the repository at this point in the history
* chore: tests showing configuration error

* fix: Connect Discovery Endpoint redirects
  • Loading branch information
dopry committed Nov 13, 2023
1 parent 862cb7a commit e038f42
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 8 deletions.
2 changes: 1 addition & 1 deletion docs/oidc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ the URLs accordingly.
ConnectDiscoveryInfoView
~~~~~~~~~~~~~~~~~~~~~~~~

Available at ``/o/.well-known/openid-configuration/``, this view provides auto
Available at ``/o/.well-known/openid-configuration``, this view provides auto
discovery information to OIDC clients, telling them the JWT issuer to use, the
location of the JWKs to verify JWTs with, the token and userinfo endpoints to
query, and other details.
Expand Down
2 changes: 1 addition & 1 deletion docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Default: ``""``
The URL of the issuer that is used in the ID token JWT and advertised in the
OIDC discovery metadata. Clients use this location to retrieve the OIDC
discovery metadata from ``OIDC_ISS_ENDPOINT`` +
``/.well-known/openid-configuration/``.
``/.well-known/openid-configuration``.

If unset, the default location is used, eg if ``django-oauth-toolkit`` is
mounted at ``/o``, it will be ``<server-address>/o``.
Expand Down
2 changes: 1 addition & 1 deletion oauth2_provider/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def oidc_issuer(self, request):
else:
raise TypeError("request must be a django or oauthlib request: got %r" % request)
abs_url = django_request.build_absolute_uri(reverse("oauth2_provider:oidc-connect-discovery-info"))
return abs_url[: -len("/.well-known/openid-configuration/")]
return abs_url[: -len("/.well-known/openid-configuration")]


oauth2_settings = OAuth2ProviderSettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS, MANDATORY)
Expand Down
6 changes: 5 additions & 1 deletion oauth2_provider/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@
]

oidc_urlpatterns = [
# .well-known/openid-configuration/ is deprecated
# https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
# does not specify a trailing slash
# Support for trailing slash should shall be removed in a future release.
re_path(
r"^\.well-known/openid-configuration/$",
r"^\.well-known/openid-configuration/?$",
views.ConnectDiscoveryInfoView.as_view(),
name="oidc-connect-discovery-info",
),
Expand Down
34 changes: 30 additions & 4 deletions tests/test_oidc_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,37 @@ def test_get_connect_discovery_info(self):
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
"claims_supported": ["sub"],
}
response = self.client.get(reverse("oauth2_provider:oidc-connect-discovery-info"))
response = self.client.get("/o/.well-known/openid-configuration")
self.assertEqual(response.status_code, 200)
assert response.json() == expected_response

def test_get_connect_discovery_info_deprecated(self):
expected_response = {
"issuer": "http://localhost/o",
"authorization_endpoint": "http://localhost/o/authorize/",
"token_endpoint": "http://localhost/o/token/",
"userinfo_endpoint": "http://localhost/o/userinfo/",
"jwks_uri": "http://localhost/o/.well-known/jwks.json",
"scopes_supported": ["read", "write", "openid"],
"response_types_supported": [
"code",
"token",
"id_token",
"id_token token",
"code token",
"code id_token",
"code id_token token",
],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256", "HS256"],
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
"claims_supported": ["sub"],
}
response = self.client.get("/o/.well-known/openid-configuration/")
self.assertEqual(response.status_code, 200)
assert response.json() == expected_response

def expect_json_response_with_rp(self, base):
def expect_json_response_with_rp_logout(self, base):
expected_response = {
"issuer": f"{base}",
"authorization_endpoint": f"{base}/authorize/",
Expand Down Expand Up @@ -83,7 +109,7 @@ def expect_json_response_with_rp(self, base):

def test_get_connect_discovery_info_with_rp_logout(self):
self.oauth2_settings.OIDC_RP_INITIATED_LOGOUT_ENABLED = True
self.expect_json_response_with_rp(self.oauth2_settings.OIDC_ISS_ENDPOINT)
self.expect_json_response_with_rp_logout(self.oauth2_settings.OIDC_ISS_ENDPOINT)

def test_get_connect_discovery_info_without_issuer_url(self):
self.oauth2_settings.OIDC_ISS_ENDPOINT = None
Expand Down Expand Up @@ -117,7 +143,7 @@ def test_get_connect_discovery_info_without_issuer_url_with_rp_logout(self):
self.oauth2_settings.OIDC_RP_INITIATED_LOGOUT_ENABLED = True
self.oauth2_settings.OIDC_ISS_ENDPOINT = None
self.oauth2_settings.OIDC_USERINFO_ENDPOINT = None
self.expect_json_response_with_rp("http://testserver/o")
self.expect_json_response_with_rp_logout("http://testserver/o")

def test_get_connect_discovery_info_without_rsa_key(self):
self.oauth2_settings.OIDC_RSA_PRIVATE_KEY = None
Expand Down

0 comments on commit e038f42

Please sign in to comment.