diff --git a/src/idpyoidc/message/oidc/__init__.py b/src/idpyoidc/message/oidc/__init__.py index a1c9949f..fe7f6c25 100644 --- a/src/idpyoidc/message/oidc/__init__.py +++ b/src/idpyoidc/message/oidc/__init__.py @@ -942,8 +942,14 @@ def verify(self, **kwargs): "token_endpoint_auth_signing_alg_values_supported" ) - if "RS256" not in self["id_token_signing_alg_values_supported"]: - raise ValueError("RS256 missing from id_token_signing_alg_values_supported") + # Check that any alg that is not "none" is supported. + # While OpenID Connect Core 1.0 says RS256 MUST be supported, + # reality has moved on and more modern alg values may be required. + if not any(i.lower() != "none" for i in self["id_token_signing_alg_values_supported"]): + raise ValueError( + "Secure signing algorithm (for example RS256 or ES256) missing from id_token_signing_alg_values_supported: %s" + % self["id_token_signing_alg_values_supported"] + ) if not parts.query and not parts.fragment: pass diff --git a/tests/test_06_oidc.py b/tests/test_06_oidc.py index 09b3b256..b6747af3 100644 --- a/tests/test_06_oidc.py +++ b/tests/test_06_oidc.py @@ -470,6 +470,7 @@ def test_example_response(self): [ "issuer", "authorization_endpoint", + "token_endpoint", "jwks_uri", "response_types_supported", "subject_types_supported", @@ -480,6 +481,7 @@ def test_required_parameters(self, required_param): provider_config = { "issuer": "https://server.example.com", "authorization_endpoint": "https://server.example.com/connect/authorize", + "token_endpoint": "https://server.example.com/connect/token", "jwks_uri": "https://server.example.com/jwks.json", "response_types_supported": ["code", "code id_token", "id_token", "token id_token"], "subject_types_supported": ["public", "pairwise"], @@ -516,6 +518,33 @@ def test_token_endpoint_is_required_for_other_than_implicit_flow_only(self): with pytest.raises(MissingRequiredAttribute): ProviderConfigurationResponse(**provider_config).verify() + def test_required_parameters_without_rs256(self): + provider_config = { + "issuer": "https://server.example.com", + "authorization_endpoint": "https://server.example.com/connect/authorize", + "token_endpoint": "https://server.example.com/connect/token", + "jwks_uri": "https://server.example.com/jwks.json", + "response_types_supported": ["code", "code id_token", "id_token", "token id_token"], + "subject_types_supported": ["public", "pairwise"], + "id_token_signing_alg_values_supported": ["none", "ES256", "HS256"], + } + + assert ProviderConfigurationResponse(**provider_config).verify() + + def test_required_parameters_only_none_signing_alg(self): + provider_config = { + "issuer": "https://server.example.com", + "authorization_endpoint": "https://server.example.com/connect/authorize", + "token_endpoint": "https://server.example.com/connect/token", + "jwks_uri": "https://server.example.com/jwks.json", + "response_types_supported": ["code", "code id_token", "id_token", "token id_token"], + "subject_types_supported": ["public", "pairwise"], + "id_token_signing_alg_values_supported": ["none"], + } + + with pytest.raises(ValueError): + ProviderConfigurationResponse(**provider_config).verify() + class TestRegistrationRequest(object): def test_deserialize(self):