IdentityPython / oidc-op

An implementation of an OIDC Provider (OP)
Apache License 2.0
64 stars 26 forks source link

WrongTokenClass bug #97

Closed nsklikas closed 3 years ago

nsklikas commented 3 years ago

I stumbled onto the followin bug. I try to run a regular code flow. When I try to exchange the authorization code with an access_token the following error is raised:

  File "/srv/venv/lib/python3.7/site-packages/oidcop/oauth2/token.py", line 407, in process_request
    _access_token, grant=True
  File "/srv/venv/lib/python3.7/site-packages/oidcop/session/manager.py", line 459, in get_session_info_by_token
    _token_info = self.token_handler.info(token_value)
  File "/srv/venv/lib/python3.7/site-packages/oidcop/token/handler.py", line 55, in info
    _handler, item_info = self.get_handler(item, order)
  File "/srv/venv/lib/python3.7/site-packages/oidcop/token/handler.py", line 75, in get_handler
    res = self.handler[typ].info(token)
  File "/srv/venv/lib/python3.7/site-packages/oidcop/token/__init__.py", line 117, in info
    raise WrongTokenClass(_res["token_class"])
oidcop.token.exception.WrongTokenClass: access_token

The bug happens because the authorization code and the access_token are created using the same class (DefaultToken). So https://github.com/IdentityPython/oidc-op/blob/0f92cfbf8079224c4c11e861a6c93d0efcf96d61/src/oidcop/token/__init__.py#L108 is called first to check if it is an authorization_code and then if it is an access_token. Both classes can decrypt the token, so https://github.com/IdentityPython/oidc-op/blob/0f92cfbf8079224c4c11e861a6c93d0efcf96d61/src/oidcop/token/__init__.py#L117 is raised.

To reproduce it you must use DefaultToken for both access token and authorization code (which is the default)

peppelinux commented 3 years ago

Great to know but I can't reproduce this yet, can you share/push a unit test for get this evidence?

nsklikas commented 3 years ago

Updated the description.

nsklikas commented 3 years ago

The config I use is


{'add_on': {'claims': {'function': 'oidcop.oidc.add_on.custom_scopes.add_custom_scopes',
                       'kwargs': {'eduperson': ['eduperson_principal_name',
                                                'eduperson_scoped_affiliation',
                                                'eduperson_targeted_id']}},
            'pkce': {'function': 'oidcop.oidc.add_on.pkce.add_pkce_support',
                     'kwargs': {'code_challenge_methods': ['plain', 'S256'],
                                'essential': False}}},
 'authz': {'class': 'oidcop.authz.AuthzHandling',
           'kwargs': {'grant_config': {'claims': {'id_token': {'eduperson_assurance': None,
                                                               'eduperson_entitlement': None,
                                                               'eduperson_orcid': None,
                                                               'eduperson_principal_name': None,
                                                               'eduperson_scoped_affiliation': None,
                                                               'eduperson_unique_id': None,
                                                               'eidas_person_identifier': None,
                                                               'email': None,
                                                               'family_name': None,
                                                               'given_name': None,
                                                               'name': None,
                                                               'schac_home_organization': None,
                                                               'schac_personal_unique_code': None,
                                                               'sub': None,
                                                               'voperson_external_affiliation': None,
                                                               'voperson_external_id': None,
                                                               'voperson_id': None},
                                                  'userinfo': {'eduperson_assurance': None,
                                                               'eduperson_entitlement': None,
                                                               'eduperson_orcid': None,
                                                               'eduperson_principal_name': None,
                                                               'eduperson_scoped_affiliation': None,
                                                               'eduperson_unique_id': None,
                                                               'eidas_person_identifier': None,
                                                               'email': None,
                                                               'family_name': None,
                                                               'given_name': None,
                                                               'name': None,
                                                               'schac_home_organization': None,
                                                               'schac_personal_unique_code': None,
                                                               'sub': None,
                                                               'voperson_external_affiliation': None,
                                                               'voperson_external_id': None,
                                                               'voperson_id': None}},
                                       'usage_rules': {'access_token': {'expires_in': 3600},
                                                       'authorization_code': {'expires_in': 300,
                                                                              'max_usage': 1,
                                                                              'supports_minting': ['access_token',
                                                                                                   'refresh_token',
                                                                                                   'id_token']},
                                                       'refresh_token': {'expires_in': 86400,
                                                                         'supports_minting': ['access_token',
                                                                                              'refresh_token',
                                                                                              'id_token']}}}}},
 'capabilities': {'claim_types_supported': ['normal'],
                  'claims_supported': ['sub',
                                       'eduperson_unique_id',
                                       'eduperson_orcid',
                                       'name',
                                       'given_name',
                                       'email',
                                       'name',
                                       'family_name',
                                       'eduperson_scoped_affiliation',
                                       'eduperson_principal_name',
                                       'eduperson_entitlement',
                                       'eduperson_assurance',
                                       'schac_personal_unique_code',
                                       'schac_home_organization',
                                       'eidas_person_identifier',
                                       'voperson_external_affiliation',
                                       'voperson_external_id',
                                       'voperson_id'],
                  'deny_unknown_scopes': True,
                  'response_types_supported': ['code'],
                  'scopes_supported': ['openid',
                                       'profile',
                                       'email',
                                       'address',
                                       'phone',
                                       'offline_access',
                                       'eduperson'],
                  'subject_types_supported': ['public', 'pairwise']},
 'claims_interface': {'class': 'oidcop.session.claims.ClaimsInterface'},
 'cookie_handler': {'class': 'oidcop.cookie_handler.CookieHandler',
                    'kwargs': {'name': {'register': 'oidc_op_rp',
                                        'session': 'oidc_op',
                                        'session_management': 'sman'}}},
 'db_conf': {'client': {'handler': 'satosa_oidc_frontend.frontend.ClientDB'},
             'default': {'handler': 'oidcmsg.storage.extension.SetGetDict'},
             'session': {'handler': 'satosa_oidc_frontend.frontend.SessionDB'}},
 'endpoint': {'authorization': {'class': 'oidcop.oidc.authorization.Authorization',
                                'kwargs': {'claim_types_supported': ['normal'],
                                           'grant_types_supported': ['authorization_code',
                                                                     'refresh_token'],
                                           'response_modes_supported': ['query'],
                                           'response_types_supported': ['code']},
                                'path': 'authorization'},
              'introspection': {'class': 'oidcop.oauth2.introspection.Introspection',
                                'kwargs': {'client_authn_method': ['client_secret_basic',
                                                                   'client_secret_post',
                                                                   'bearer_header',
                                                                   'bearer_body',
                                                                   'client_secret_jwt',
                                                                   'private_key_jwt'],
                                           'enable_claims_per_client': False},
                                'path': 'introspect'},
              'provider_config': {'class': 'oidcop.oidc.provider_config.ProviderConfiguration',
                                  'path': '.well-known/openid-configuration'},
              'registration': {'class': 'oidcop.oidc.registration.Registration',
                               'kwargs': {'client_authn_method': ['bearer_header',
                                                                  'bearer_body'],
                                          'client_secret_expiration_time': 0},
                               'path': 'register'},
              'token': {'class': 'oidcop.oidc.token.Token',
                        'kwargs': {'allow_refresh': True,
                                   'client_authn_method': ['client_secret_basic',
                                                           'client_secret_post',
                                                           'bearer_header',
                                                           'bearer_body',
                                                           'client_secret_jwt',
                                                           'private_key_jwt']},
                        'path': 'token'},
              'userinfo': {'class': 'oidcop.oidc.userinfo.UserInfo',
                           'kwargs': {'claim_types_supported': ['normal'],
                                      'client_authn_method': ['client_secret_basic',
                                                              'client_secret_post',
                                                              'bearer_header',
                                                              'bearer_body',
                                                              'client_secret_jwt',
                                                              'private_key_jwt']},
                           'path': 'userinfo'}},
 'issuer': 'issuer',
 'keys': {'key_defs': [{'type': 'RSA', 'use': ['sig']},
                       {'type': 'RSA', 'use': ['sig']},
                       {'crv': 'P-256', 'type': 'EC', 'use': ['sig']}],
          'private_path': None,
          'public_path': None,
          'read_only': False,
          'uri_path': 'jwks'},
 'session_params': {'sub_func': {'public': {...}}},
 'template_handler': None,
 'token_handler_args': {'code': {'kwargs': {'lifetime': 300}},
                        'id_token': {'class': 'oidcop.token.id_token.IDToken',
                                     'kwargs': {'base_claims': {},
                                                'enable_claims_per_client': False,
                                                'lifetime': 300}},
                        'jwks_def': {'key_defs': [{'bytes': 24,
                                                   'kid': 'code',
                                                   'type': 'oct',
                                                   'use': ['enc']},
                                                  {'bytes': 24,
                                                   'kid': 'refresh',
                                                   'type': 'oct',
                                                   'use': ['enc']},
                                                  {'bytes': 24,
                                                   'kid': 'token',
                                                   'type': 'oct',
                                                   'use': ['enc']}],
                                     'private_path': None,
                                     'read_only': True},
                        'jwks_file': None,
                        'refresh': {'kwargs': {'lifetime': 86400}},
                        'token': {'kwargs': {'lifetime': 3600}}},
 'userinfo': {'class': 'oidcop.user_info.UserInfo'}},
 'verify_ssl': True}