예제 #1
0
 def _get_approved_attributes(self, provider_supported_claims, authn_req):
     requested_claims = list(scope2claims(authn_req["scope"]).keys())
     if "claims" in authn_req:
         for k in ["id_token", "userinfo"]:
             if k in authn_req["claims"]:
                 requested_claims.extend(authn_req["claims"][k].keys())
     return set(provider_supported_claims).intersection(set(requested_claims))
예제 #2
0
파일: provider.py 프로젝트: valintepes/pyop
    def handle_userinfo_request(self, request=None, http_headers=None):
        # type: (Optional[str], Optional[Mapping[str, str]]) -> oic.oic.message.OpenIDSchema
        """
        Handles a userinfo request.
        :param request: urlencoded request (either query string or POST body)
        :param http_headers: http headers
        """
        if http_headers is None:
            http_headers = {}
        userinfo_request = dict(parse_qsl(request))
        bearer_token = extract_bearer_token_from_http_request(
            userinfo_request, http_headers.get('Authorization'))

        introspection = self.authz_state.introspect_access_token(bearer_token)
        if not introspection['active']:
            raise InvalidAccessToken('The access token has expired')
        scope = introspection['scope']
        user_id = self.authz_state.get_user_id_for_subject_identifier(
            introspection['sub'])

        requested_claims = scope2claims(scope.split())
        authentication_request = self.authz_state.get_authorization_request_for_access_token(
            bearer_token)
        requested_claims.update(
            self._get_requested_claims_in(authentication_request, 'userinfo'))
        user_claims = self.userinfo.get_claims_for(user_id, requested_claims)

        user_claims.setdefault('sub', introspection['sub'])
        response = OpenIDSchema(**user_claims)
        logger.debug('userinfo=%s from requested_claims=%s userinfo=%s',
                     response, requested_claims, user_claims)
        return response
예제 #3
0
 def _get_approved_attributes(self, provider_supported_claims, authn_req):
     requested_claims = list(scope2claims(authn_req["scope"]).keys())
     if "claims" in authn_req:
         for k in ["id_token", "userinfo"]:
             if k in authn_req["claims"]:
                 requested_claims.extend(authn_req["claims"][k].keys())
     return set(provider_supported_claims).intersection(set(requested_claims))
예제 #4
0
    def authorize(self, authentication_request,  # type: oic.oic.message.AuthorizationRequest
                  user_id,  # type: str
                  extra_id_token_claims=None
                  # type: Optional[Union[Mapping[str, Union[str, List[str]]], Callable[[str, str], Mapping[str, Union[str, List[str]]]]]
                  ):
        # type: (...) -> oic.oic.message.AuthorizationResponse
        """
        Creates an Authentication Response for the specified authentication request and local identifier of the
        authenticated user.
        """
        custom_sub = self.userinfo[user_id].get('sub')
        if custom_sub:
            self.authz_state.subject_identifiers[user_id] = {'public': custom_sub}
            sub = custom_sub
        else:
            sub = self._create_subject_identifier(user_id, authentication_request['client_id'],
                                                  authentication_request['redirect_uri'])

        self._check_subject_identifier_matches_requested(authentication_request, sub)
        response = AuthorizationResponse()

        authz_code = None
        if 'code' in authentication_request['response_type']:
            authz_code = self.authz_state.create_authorization_code(authentication_request, sub)
            response['code'] = authz_code

        access_token_value = None
        if 'token' in authentication_request['response_type']:
            access_token = self.authz_state.create_access_token(authentication_request, sub)
            access_token_value = access_token.value
            self._add_access_token_to_response(response, access_token)

        if 'id_token' in authentication_request['response_type']:
            if extra_id_token_claims is None:
                extra_id_token_claims = {}
            elif callable(extra_id_token_claims):
                extra_id_token_claims = extra_id_token_claims(user_id, authentication_request['client_id'])

            requested_claims = self._get_requested_claims_in(authentication_request, 'id_token')
            if len(authentication_request['response_type']) == 1:
                # only id token is issued -> no way of doing userinfo request, so include all claims in ID Token,
                # even those requested by the scope parameter
                requested_claims.update(
                    scope2claims(
                        authentication_request['scope'], extra_scope_dict=self.extra_scopes
                    )
                )

            user_claims = self.userinfo.get_claims_for(user_id, requested_claims)
            response['id_token'] = self._create_signed_id_token(authentication_request['client_id'], sub,
                                                                user_claims,
                                                                authentication_request.get('nonce'),
                                                                authz_code, access_token_value, extra_id_token_claims)
            logger.debug('issued id_token=%s from requested_claims=%s userinfo=%s extra_claims=%s',
                         response['id_token'], requested_claims, user_claims, extra_id_token_claims)

        if 'state' in authentication_request:
            response['state'] = authentication_request['state']
        return response
 def test_scope2claims_with_non_standard_scope(self):
     claims = scope2claims(['my_scope', 'email'])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS['email'])
 def test_scope2claims(self):
     claims = scope2claims(['profile', 'email'])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS['profile'] + SCOPE2CLAIMS['email'])
예제 #7
0
 def test_scope2claims_extra_scope_dict(self):
     claims = scope2claims(["my_scope", "email"],
                           extra_scope_dict={"my_scope": ["my_attribute"]})
     assert sorted(
         claims.keys()) == ["email", "email_verified", "my_attribute"]
예제 #8
0
 def test_scope2claims_with_non_standard_scope(self):
     claims = scope2claims(["my_scope", "email"])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS["email"])
예제 #9
0
 def test_scope2claims(self):
     claims = scope2claims(["profile", "email"])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS["profile"] +
                                              SCOPE2CLAIMS["email"])
예제 #10
0
 def test_scope2claims_extra_scope_dict(self):
     claims = scope2claims(['my_scope', 'email'],
                           extra_scope_dict={'my_scope': ['my_attribute']})
     assert sorted(
         claims.keys()) == ['email', 'email_verified', 'my_attribute']
예제 #11
0
 def test_scope2claims_with_non_standard_scope(self):
     claims = scope2claims(['my_scope', 'email'])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS['email'])
예제 #12
0
 def test_scope2claims(self):
     claims = scope2claims(['profile', 'email'])
     assert Counter(claims.keys()) == Counter(SCOPE2CLAIMS['profile'] +
                                              SCOPE2CLAIMS['email'])
예제 #13
0
 def test_scope2claims_extra_scope_dict(self):
     claims = scope2claims(['my_scope', 'email'], extra_scope_dict={'my_scope': ['my_attribute']})
     assert sorted(claims.keys()) == ['email', 'email_verified', 'my_attribute']