Beispiel #1
0
    def verify(self, provider_capabilities, provider_software_statement, client_preferences,
               client_software_statement):
        # type: (Mapping[str, Union[str, Sequence[str]]],
        #        Mapping[str, Union[str, Sequence[str]]],
        #        Mapping[str, Union[str, Sequence[str]]],
        #        Mapping[str, Union[str, Sequence[str]]]) -> Dict[str, Union[str, List[str]]]
        """
        Verify the provider can satisfy the client's registration request.


        Negotiates the metadata parameters combined from the provider metadata, provider software
        statement, client metadata, and client software statement.

        :param provider_capabilities: provider metadata
        :param provider_software_statement: provider software statement
        :param client_preferences: client metadata
        :param client_software_statement: client software statement
        :raise OIDCFederationError: if the client metadata can't be matched with the provider's
                                    capabilities
        :return: the "negotiated" client metadata parameters that overrides/extends the initial
                 registration request
        """
        client_preferences = copy.deepcopy(client_preferences)
        client_preferences.update(client_software_statement)
        provider_capabilities = copy.deepcopy(provider_capabilities)
        provider_capabilities.update(provider_software_statement)

        client_preferences.update(
                self._match_array_preferences(client_preferences, provider_capabilities))

        for client_preference, provider_capability in [v for v in
                                                       PREFERENCE2PROVIDER.items() if
                                                       v not in RegistrationRequestVerification.METADATA_AS_ARRAYS]:
            if client_preference not in client_preferences and provider_capability in provider_software_statement:
                # default to metadata from provider software statement to ensure restrictions from
                # the federation are applied
                restrictions = provider_software_statement[provider_capability]
                # just select the first, but could be some smarter heuristic
                client_preferences[client_preference] = restrictions[0]
                continue

            try:
                client_value = client_preferences[client_preference]
                provider_values = provider_capabilities[provider_capability]
            except KeyError:
                continue

            if client_value not in provider_values:
                raise OIDCFederationError(
                        "Mismatch in registration request: {} '{}' not in {} '{}'.".format(
                                client_preference, client_value, provider_capability,
                                provider_values))

        return client_preferences
Beispiel #2
0
 def match_client_request(self, request):
     for _pref, _prov in PREFERENCE2PROVIDER.items():
         if _pref in request:
             if _pref == "response_types":
                 for val in request[_pref]:
                     match = False
                     p = set(val.split(" "))
                     for cv in self.capabilities[_prov]:
                         if p == set(cv.split(" ")):
                             match = True
                             break
                     if not match:
                         raise CapabilitiesMisMatch("Not allowed {}".format(_pref))
             else:
                 if isinstance(request[_pref], str):
                     if request[_pref] not in self.capabilities[_prov]:
                         raise CapabilitiesMisMatch("Not allowed {}".format(_pref))
                 else:
                     if not set(request[_pref]).issubset(
                         set(self.capabilities[_prov])
                     ):
                         raise CapabilitiesMisMatch("Not allowed {}".format(_pref))
Beispiel #3
0
 def match_client_request(self, request):
     for _pref, _prov in PREFERENCE2PROVIDER.items():
         if _pref in request:
             if _pref == "response_types":
                 for val in request[_pref]:
                     match = False
                     p = set(val.split(" "))
                     for cv in self.capabilities[_prov]:
                         if p == set(cv.split(' ')):
                             match = True
                             break
                     if not match:
                         raise CapabilitiesMisMatch(
                             'Not allowed {}'.format(_pref))
             else:
                 if isinstance(request[_pref], six.string_types):
                     if request[_pref] not in self.capabilities[_prov]:
                         raise CapabilitiesMisMatch(
                             'Not allowed {}'.format(_pref))
                 else:
                     if not set(request[_pref]).issubset(
                             set(self.capabilities[_prov])):
                         raise CapabilitiesMisMatch(
                             'Not allowed {}'.format(_pref))