Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

id_token_signing_alg_values_supported hard-coded to RS256 #110

Closed
jinnatar opened this issue Aug 6, 2024 · 1 comment · Fixed by #111
Closed

id_token_signing_alg_values_supported hard-coded to RS256 #110

jinnatar opened this issue Aug 6, 2024 · 1 comment · Fixed by #111

Comments

@jinnatar
Copy link
Contributor

jinnatar commented Aug 6, 2024

The verify code at:
https://github.com/IdentityPython/idpy-oidc/blob/main/src/idpyoidc/message/oidc/__init__.py#L945 hardcodes checking that the OP supports RS256 for id_token_signing. There doesn't seem to be any config option that would allow overriding this and thus OPs that on purpose require better algorithms cannot be supported. In my case Kanidm requires ES256 be used, and signals so in discovery.

Defining a config item id_token_signing_alg_values_supported is respected and reflected in the entity registration, but said registered entity is apparently not used when checking what signing algo should be supported.

Full example that fails against Kanidm when used via SaToSa as a backend:

---
module: satosa.backends.idpy_oidc.IdpyOIDCBackend
name: !ENV OIDC_NAME
config:
  client_type: oidc
  client:
    provider_info:
      issuer: !ENV OIDC_ISSUER_URL

    scopes_supported: [openid, profile, email]
    response_types_supported: [code]
    id_token_signing_alg_values_supported: [ES256]
    subject_types_supported: [public]

    client_id: !ENV OIDC_CLIENT_ID
    client_secret: !ENV OIDC_CLIENT_SECRET
    redirect_uris: [<base_url>/<name>]

Failure via SaToSa load:

[2024-08-06 11:51:29 +0000] [1] [INFO] Starting gunicorn 22.0.0
[2024-08-06 11:51:29 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2024-08-06 11:51:29 +0000] [1] [INFO] Using worker: sync
[2024-08-06 11:51:29 +0000] [7] [INFO] Booting worker with pid: 7
[2024-08-06 11:51:29,527][INFO][satosa.proxy_server.make_app] Running SATOSA version 8.4.0
[2024-08-06 11:51:29,527][INFO][satosa.base.__init__] Loading backend modules...
[2024-08-06 11:51:29,710][DEBUG][idpyoidc.client.claims.transform.preferred_to_registered] Entity registered: {'client_id': 'ceph', 'client_secret': 'xxxxx', 'redirect_uris': ['saml.example.com/kanidm_ceph'], 'response_types': ['code'], 'grant_types': ['authorization_code', 'refresh_token'], 'application_type': 'web', 'subject_type': 'public', 'id_token_signed_response_alg': 'ES256', 'userinfo_signed_response_alg': 'RS256', 'request_object_signing_alg': 'RS256', 'token_endpoint_auth_method': 'client_secret_basic', 'token_endpoint_auth_signing_alg': 'RS256', 'default_max_age': 86400, 'response_modes': ['query', 'fragment', 'form_post'], 'scope': ['openid', 'profile', 'email'], 'callback_uris': {'redirect_uris': {'query': ['saml.example.com/kanidm_ceph']}}, 'encrypt_request_object_supported': False, 'encrypt_userinfo_supported': False}
[2024-08-06 11:51:29,710][DEBUG][idpyoidc.client.oauth2.stand_alone_client.do_provider_info] ******************** do_provider_info ********************
[2024-08-06 11:51:29,711][DEBUG][idpyoidc.client.oauth2.dynamic_provider_info_discovery] provider_info
[2024-08-06 11:51:29,711][DEBUG][idpyoidc.client.oauth2.do_request] do_request info: {'url': 'https://idm.example.com/oauth2/openid/ceph/.well-known/openid-configuration', 'method': 'GET'}
[2024-08-06 11:51:29,711][DEBUG][idpyoidc.client.oauth2.service_request] Doing request with: URL:https://idm.example.com/oauth2/openid/ceph/.well-known/openid-configuration, method:GET, data:None, https_args:{}
[2024-08-06 11:51:29,712][DEBUG][urllib3.connectionpool._new_conn] Starting new HTTPS connection (1): idm.example.com:443
[2024-08-06 11:51:29,746][DEBUG][urllib3.connectionpool._make_request] https://idm.example.com:443 "GET /oauth2/openid/ceph/.well-known/openid-configuration HTTP/11" 200 1019
[2024-08-06 11:51:29,746][DEBUG][idpyoidc.client.oauth2.parse_request_response] response_body_type: "json"
[2024-08-06 11:51:29,746][DEBUG][idpyoidc.client.util.get_deserialization_method] resp.headers: {'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-store no-cache max-age=0', 'Content-Length': '1019', 'Content-Security-Policy': "base-uri 'self' https:; default-src 'self'; form-action 'self' https:; frame-ancestors 'none'; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'sha384-xxx' 'sha384-xxx' 'sha384-xxx' 'sha384-xxx' 'sha384-xxx' 'sha384-xxx'; worker-src 'none';", 'Content-Type': 'application/json', 'Date': 'Tue, 06 Aug 2024 11:51:29 GMT', 'Permissions-Policy': 'fullscreen=(), geolocation=()', 'Pragma': 'no-cache', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Set-Cookie': 'idm-prod-sticky=xxx; Path=/', 'Strict-Transport-Security': 'max-age=86400', 'X-Content-Type-Options': 'nosniff', 'X-Kanidm-Opid': '6da1850f-4012-45fa-8825-b91bfc9f6c3f', 'X-Kanidm-Version': '1.2.2'}
[2024-08-06 11:51:29,746][DEBUG][idpyoidc.client.util.get_deserialization_method] resp.txt: {"issuer":"https://idm.example.com/oauth2/openid/ceph","authorization_endpoint":"https://idm.example.com/ui/oauth2","token_endpoint":"https://idm.example.com/oauth2/token","userinfo_endpoint":"https://idm.example.com/oauth2/openid/ceph/userinfo","jwks_uri":"https://idm.example.com/oauth2/openid/ceph/public_key.jwk","scopes_supported":["email","openid","profile"],"response_types_supported":["code"],"response_modes_supported":["query"],"grant_types_supported":["authorization_code"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["ES256"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"display_values_supported":["page"],"claim_types_supported":["normal"],"service_documentation":"https://kanidm.github.io/kanidm/master/integrations/oauth2.html","claims_parameter_supported":false,"request_parameter_supported":false,"request_uri_parameter_supported":false,"require_request_uri_registration":false,"code_challenge_methods_supported":["S256"]}
[2024-08-06 11:51:29,746][DEBUG][idpyoidc.client.oauth2.parse_request_response] Successful response: {"issuer":"https://idm.example.com/oauth2/openid/ceph","authorization_endpoint":"https://idm.example.com/ui/oauth2","token_endpoint":"https://idm.example.com/oauth2/token","userinfo_endpoint":"https://idm.example.com/oauth2/openid/ceph/userinfo","jwks_uri":"https://idm.example.com/oauth2/openid/ceph/public_key.jwk","scopes_supported":["email","openid","profile"],"response_types_supported":["code"],"response_modes_supported":["query"],"grant_types_supported":["authorization_code"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["ES256"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"display_values_supported":["page"],"claim_types_supported":["normal"],"service_documentation":"https://kanidm.github.io/kanidm/master/integrations/oauth2.html","claims_parameter_supported":false,"request_parameter_supported":false,"request_uri_parameter_supported":false,"require_request_uri_registration":false,"code_challenge_methods_supported":["S256"]}
[2024-08-06 11:51:29,747][DEBUG][idpyoidc.client.service.parse_response] response format: json
[2024-08-06 11:51:29,747][DEBUG][idpyoidc.client.service.parse_response] response_cls: ProviderConfigurationResponse
[2024-08-06 11:51:29,747][DEBUG][idpyoidc.client.service.parse_response] Initial response parsing => "{'version': '3.0', 'token_endpoint_auth_methods_supported': ['client_secret_basic', 'client_secret_post'], 'claims_parameter_supported': False, 'request_parameter_supported': False, 'request_uri_parameter_supported': False, 'require_request_uri_registration': False, 'grant_types_supported': ['authorization_code'], 'issuer': 'https://idm.example.com/oauth2/openid/ceph', 'authorization_endpoint': 'https://idm.example.com/ui/oauth2', 'token_endpoint': 'https://idm.example.com/oauth2/token', 'userinfo_endpoint': 'https://idm.example.com/oauth2/openid/ceph/userinfo', 'jwks_uri': 'https://idm.example.com/oauth2/openid/ceph/public_key.jwk', 'scopes_supported': ['email', 'openid', 'profile'], 'response_types_supported': ['code'], 'response_modes_supported': ['query'], 'subject_types_supported': ['public'], 'id_token_signing_alg_values_supported': ['ES256'], 'display_values_supported': ['page'], 'claim_types_supported': ['normal'], 'service_documentation': 'https://kanidm.github.io/kanidm/master/integrations/oauth2.html', 'code_challenge_methods_supported': ['S256']}"
[2024-08-06 11:51:29,747][DEBUG][idpyoidc.client.service.parse_response] Verify response with {'iss': 'https://idm.example.com/oauth2/openid/ceph', 'keyjar': <KeyJar(issuers=['ceph', ''])>, 'verify': True, 'client_id': 'ceph'}
[2024-08-06 11:51:29,747][ERROR][idpyoidc.client.service.parse_response] Got exception while verifying response: RS256 missing from id_token_signing_alg_values_supported
[2024-08-06 11:51:29,747][ERROR][idpyoidc.client.oauth2.parse_request_response] RS256 missing from id_token_signing_alg_values_supported
[2024-08-06 11:51:29,748][ERROR][satosa.proxy_server.make_app] Failed to create WSGI app.
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/satosa/proxy_server.py", line 197, in make_app
    res1 = WsgiApplication(satosa_config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/satosa/proxy_server.py", line 119, in __init__
    super().__init__(config)
  File "/usr/local/lib/python3.12/site-packages/satosa/base.py", line 56, in __init__
    backends = load_backends(self.config, self._auth_resp_callback_func,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/satosa/plugin_loader.py", line 44, in load_backends
    backend_modules = _load_plugins(
                      ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/satosa/plugin_loader.py", line 181, in _load_plugins
    instance = module_class(callback, internal_attributes, module_config, base_url,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/satosa/backends/idpy_oidc.py", line 52, in __init__
    self.client.do_provider_info()
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/stand_alone_client.py", line 69, in do_provider_info
    dynamic_provider_info_discovery(self, behaviour_args=behaviour_args)
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/__init__.py", line 339, in dynamic_provider_info_discovery
    response = client.do_request(service, behaviour_args=behaviour_args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/__init__.py", line 136, in do_request
    return self.service_request(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/__init__.py", line 223, in service_request
    response = _get_response_func(
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/__init__.py", line 190, in get_response
    return self.parse_request_response(service, resp, response_body_type, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/oauth2/__init__.py", line 273, in parse_request_response
    return service.parse_response(reqresp.text, value_type, state, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/client/service.py", line 671, in parse_response
    resp.verify(**vargs)
  File "/usr/local/lib/python3.12/site-packages/idpyoidc/message/oidc/__init__.py", line 946, in verify
    raise ValueError("RS256 missing from id_token_signing_alg_values_supported")
ValueError: RS256 missing from id_token_signing_alg_values_supported
[2024-08-06 11:51:29 +0000] [1] [ERROR] Worker (pid:7) exited with code 3
[2024-08-06 11:51:29 +0000] [1] [ERROR] Shutting down: Master
[2024-08-06 11:51:29 +0000] [1] [ERROR] Reason: Worker failed to boot.
@jinnatar
Copy link
Contributor Author

jinnatar commented Aug 6, 2024

For testing I changed the line to instead look for ES256. This allows validation to pass and auth works fine after this, even if I don't manually specify id_token_signing_alg_values_supported.

If the check is necessary, it should be expanded to other algos, or perhaps take the OP discovery id_token_signing_alg_values_supported and check for the algos given there.

Ooor, the smallest dumbest fix would be to check for either RS256 or ES256, I don't have the context for why this check was necessary in the first place. :-)

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 a pull request may close this issue.

1 participant