Esempio n. 1
0
    def _create_code(self):
        """
        Generate a valid grant code.
        """
        code = create_code(user=self.user,
                           client=self.client,
                           scope=['openid', 'email'],
                           nonce=FAKE_NONCE,
                           is_authentication=True)
        code.save()

        return code
    def _create_code(self, scope=None):
        """
        Generate a valid grant code.
        """
        code = create_code(
            user=self.user,
            client=self.client,
            scope=(scope if scope else TokenTestCase.SCOPE_LIST),
            nonce=FAKE_NONCE,
            is_authentication=True)
        code.save()

        return code
    def _create_code(self):
        """
        Generate a valid grant code.
        """
        code = create_code(
            user=self.user,
            client=self.client,
            scope=['openid', 'email'],
            nonce=FAKE_NONCE,
            is_authentication=True)
        code.save()

        return code
    def test_pkce_parameters(self):
        """
        Test Proof Key for Code Exchange by OAuth Public Clients.
        https://tools.ietf.org/html/rfc7636
        """
        code = create_code(user=self.user, client=self.client,
                           scope=['openid', 'email'], nonce=FAKE_NONCE, is_authentication=True,
                           code_challenge=FAKE_CODE_CHALLENGE, code_challenge_method='S256')
        code.save()

        post_data = self._auth_code_post_data(code=code.code)

        # Add parameters.
        post_data['code_verifier'] = FAKE_CODE_VERIFIER

        response = self._post_request(post_data)

        response_dic = json.loads(response.content.decode('utf-8'))
    def test_pkce_parameters(self):
        """
        Test Proof Key for Code Exchange by OAuth Public Clients.
        https://tools.ietf.org/html/rfc7636
        """
        code = create_code(user=self.user, client=self.client,
                           scope=['openid', 'email'], nonce=FAKE_NONCE, is_authentication=True,
                           code_challenge=FAKE_CODE_CHALLENGE, code_challenge_method='S256')
        code.save()

        post_data = self._auth_code_post_data(code=code.code)

        # Add parameters.
        post_data['code_verifier'] = FAKE_CODE_VERIFIER

        response = self._post_request(post_data)

        response_dic = json.loads(response.content.decode('utf-8'))
Esempio n. 6
0
    def test_pkce_missing_code_verifier(self):
        """
        Test that a request to the token endpoint without the PKCE parameter
        fails when PKCE was used during the authorization request.
        """

        code = create_code(user=self.user,
                           client=self.client,
                           scope=['openid', 'email'],
                           nonce=FAKE_NONCE,
                           is_authentication=True,
                           code_challenge=FAKE_CODE_CHALLENGE,
                           code_challenge_method='S256')
        code.save()

        post_data = self._auth_code_post_data(code=code.code)

        assert 'code_verifier' not in post_data

        response = self._post_request(post_data)

        assert json.loads(
            response.content.decode('utf-8')).get('error') == 'invalid_grant'
    def create_response_uri(self):
        uri = urlsplit(self.params['redirect_uri'])
        query_params = parse_qs(uri.query)
        query_fragment = {}

        try:
            if self.grant_type in ['authorization_code', 'hybrid']:
                code = create_code(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params['scope'],
                    nonce=self.params['nonce'],
                    is_authentication=self.is_authentication,
                    code_challenge=self.params['code_challenge'],
                    code_challenge_method=self.params['code_challenge_method'])
                code.save()

            if self.grant_type == 'authorization_code':
                query_params['code'] = code.code
                query_params['state'] = self.params['state'] if self.params[
                    'state'] else ''
            elif self.grant_type in ['implicit', 'hybrid']:
                token = create_token(user=self.request.user,
                                     client=self.client,
                                     scope=self.params['scope'])

                # Check if response_type must include access_token in the response.
                if (self.params['response_type'] in [
                        'id_token token', 'token', 'code token',
                        'code id_token token'
                ]):
                    query_fragment['access_token'] = token.access_token

                # We don't need id_token if it's an OAuth2 request.
                if self.is_authentication:
                    kwargs = {
                        'token': token,
                        'user': self.request.user,
                        'aud': self.client.client_id,
                        'nonce': self.params['nonce'],
                        'request': self.request,
                        'scope': self.params['scope'],
                    }
                    # Include at_hash when access_token is being returned.
                    if 'access_token' in query_fragment:
                        kwargs['at_hash'] = token.at_hash
                    id_token_dic = create_id_token(**kwargs)

                    # Check if response_type must include id_token in the response.
                    if self.params['response_type'] in [
                            'id_token', 'id_token token', 'code id_token',
                            'code id_token token'
                    ]:
                        query_fragment['id_token'] = encode_id_token(
                            id_token_dic, self.client)
                else:
                    id_token_dic = {}

                # Store the token.
                token.id_token = id_token_dic
                token.save()

                # Code parameter must be present if it's Hybrid Flow.
                if self.grant_type == 'hybrid':
                    query_fragment['code'] = code.code

                query_fragment['token_type'] = 'bearer'

                query_fragment['expires_in'] = settings.get(
                    'OIDC_TOKEN_EXPIRE')

                query_fragment['state'] = self.params['state'] if self.params[
                    'state'] else ''

            if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
                # Generate client origin URI from the redirect_uri param.
                redirect_uri_parsed = urlsplit(self.params['redirect_uri'])
                client_origin = '{0}://{1}'.format(redirect_uri_parsed.scheme,
                                                   redirect_uri_parsed.netloc)

                # Create random salt.
                salt = md5(uuid4().hex.encode()).hexdigest()

                # The generation of suitable Session State values is based
                # on a salted cryptographic hash of Client ID, origin URL,
                # and OP browser state.
                session_state = '{client_id} {origin} {browser_state} {salt}'.format(
                    client_id=self.client.client_id,
                    origin=client_origin,
                    browser_state=get_browser_state_or_default(self.request),
                    salt=salt)
                session_state = sha256(
                    session_state.encode('utf-8')).hexdigest()
                session_state += '.' + salt
                if self.grant_type == 'authorization_code':
                    query_params['session_state'] = session_state
                elif self.grant_type in ['implicit', 'hybrid']:
                    query_fragment['session_state'] = session_state

        except Exception as error:
            logger.exception(
                '[Authorize] Error when trying to create response uri: %s',
                error)
            raise AuthorizeError(self.params['redirect_uri'], 'server_error',
                                 self.grant_type)

        uri = uri._replace(query=urlencode(query_params, doseq=True),
                           fragment=uri.fragment +
                           urlencode(query_fragment, doseq=True))

        return urlunsplit(uri)
Esempio n. 8
0
    def create_response_uri(self):
        uri = urlsplit(self.params.redirect_uri)
        query_params = parse_qs(uri.query)
        query_fragment = parse_qs(uri.fragment)

        try:
            if self.grant_type == 'authorization_code':
                code = create_code(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params.scope,
                    nonce=self.params.nonce,
                    is_authentication=self.is_authentication,
                    code_challenge=self.params.code_challenge,
                    code_challenge_method=self.params.code_challenge_method)

                code.save()

                query_params['code'] = code.code
                query_params['state'] = self.params.state if self.params.state else ''

            elif self.grant_type == 'implicit':
                token = create_token(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params.scope)

                # Check if response_type is an OpenID request with value 'id_token token'
                # or it's an OAuth2 Implicit Flow request.
                if self.params.response_type in ['id_token token', 'token']:
                    query_fragment['access_token'] = token.access_token

                # We don't need id_token if it's an OAuth2 request.
                if self.is_authentication:
                    kwargs = {
                        "user": self.request.user,
                        "aud": self.client.client_id,
                        "nonce": self.params.nonce,
                        "request": self.request
                    }
                    # Include at_hash when access_token is being returned.
                    if 'access_token' in query_fragment:
                        kwargs['at_hash'] = token.at_hash
                    id_token_dic = create_id_token(**kwargs)
                    query_fragment['id_token'] = encode_id_token(id_token_dic, self.client)
                    token.id_token = id_token_dic
                else:
                    id_token_dic = {}

                # Store the token.
                token.id_token = id_token_dic
                token.save()

                query_fragment['token_type'] = 'bearer'
                # TODO: Create setting 'OIDC_TOKEN_EXPIRE'.
                query_fragment['expires_in'] = 60 * 10

                query_fragment['state'] = self.params.state if self.params.state else ''

        except Exception as error:
            logger.debug('[Authorize] Error when trying to create response uri: %s', error)
            raise AuthorizeError(
                self.params.redirect_uri,
                'server_error',
                self.grant_type)

        uri = uri._replace(query=urlencode(query_params, doseq=True))
        uri = uri._replace(fragment=urlencode(query_fragment, doseq=True))

        return urlunsplit(uri)
Esempio n. 9
0
    def create_response_uri(self):
        uri = urlsplit(self.params['redirect_uri'])
        query_params = parse_qs(uri.query)
        query_fragment = parse_qs(uri.fragment)

        try:
            if self.grant_type in ['authorization_code', 'hybrid']:
                code = create_code(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params['scope'],
                    nonce=self.params['nonce'],
                    is_authentication=self.is_authentication,
                    code_challenge=self.params['code_challenge'],
                    code_challenge_method=self.params['code_challenge_method'])
                code.save()

            if self.grant_type == 'authorization_code':
                query_params['code'] = code.code
                query_params['state'] = self.params['state'] if self.params['state'] else ''
            elif self.grant_type in ['implicit', 'hybrid']:
                token = create_token(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params['scope'])

                # Check if response_type must include access_token in the response.
                if self.params['response_type'] in ['id_token token', 'token', 'code token', 'code id_token token']:
                    query_fragment['access_token'] = token.access_token

                # We don't need id_token if it's an OAuth2 request.
                if self.is_authentication:
                    kwargs = {
                        'user': self.request.user,
                        'aud': self.client.client_id,
                        'nonce': self.params['nonce'],
                        'request': self.request,
                        'scope': self.params['scope'],
                    }
                    # Include at_hash when access_token is being returned.
                    if 'access_token' in query_fragment:
                        kwargs['at_hash'] = token.at_hash
                    id_token_dic = create_id_token(**kwargs)

                    # Check if response_type must include id_token in the response.
                    if self.params['response_type'] in ['id_token', 'id_token token', 'code id_token', 'code id_token token']:
                        query_fragment['id_token'] = encode_id_token(id_token_dic, self.client)
                else:
                    id_token_dic = {}

                # Store the token.
                token.id_token = id_token_dic
                token.save()

                # Code parameter must be present if it's Hybrid Flow.
                if self.grant_type == 'hybrid':
                    query_fragment['code'] = code.code

                query_fragment['token_type'] = 'bearer'

                query_fragment['expires_in'] = settings.get('OIDC_TOKEN_EXPIRE')

                query_fragment['state'] = self.params['state'] if self.params['state'] else ''

        except Exception as error:
            logger.debug('[Authorize] Error when trying to create response uri: %s', error)
            raise AuthorizeError(self.params['redirect_uri'], 'server_error', self.grant_type)

        uri = uri._replace(query=urlencode(query_params, doseq=True))
        uri = uri._replace(fragment=urlencode(query_fragment, doseq=True))

        return urlunsplit(uri)
    def create_response_uri(self):
        uri = urlsplit(self.params['redirect_uri'])
        query_params = parse_qs(uri.query)
        query_fragment = parse_qs(uri.fragment)

        try:
            if self.grant_type in ['authorization_code', 'hybrid']:
                code = create_code(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params['scope'],
                    nonce=self.params['nonce'],
                    is_authentication=self.is_authentication,
                    code_challenge=self.params['code_challenge'],
                    code_challenge_method=self.params['code_challenge_method'])
                code.save()

            if self.grant_type == 'authorization_code':
                query_params['code'] = code.code
                query_params['state'] = self.params['state'] if self.params['state'] else ''
            elif self.grant_type in ['implicit', 'hybrid']:
                token = create_token(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params['scope'])

                # Check if response_type must include access_token in the response.
                if self.params['response_type'] in ['id_token token', 'token', 'code token', 'code id_token token']:
                    query_fragment['access_token'] = token.access_token

                # We don't need id_token if it's an OAuth2 request.
                if self.is_authentication:
                    kwargs = {
                        'user': self.request.user,
                        'aud': self.client.client_id,
                        'nonce': self.params['nonce'],
                        'request': self.request,
                        'scope': self.params['scope'],
                    }
                    # Include at_hash when access_token is being returned.
                    if 'access_token' in query_fragment:
                        kwargs['at_hash'] = token.at_hash
                    id_token_dic = create_id_token(**kwargs)

                    # Check if response_type must include id_token in the response.
                    if self.params['response_type'] in ['id_token', 'id_token token', 'code id_token', 'code id_token token']:
                        query_fragment['id_token'] = encode_id_token(id_token_dic, self.client)
                else:
                    id_token_dic = {}

                # Store the token.
                token.id_token = id_token_dic
                token.save()

                # Code parameter must be present if it's Hybrid Flow.
                if self.grant_type == 'hybrid':
                    query_fragment['code'] = code.code

                query_fragment['token_type'] = 'bearer'

                query_fragment['expires_in'] = settings.get('OIDC_TOKEN_EXPIRE')

                query_fragment['state'] = self.params['state'] if self.params['state'] else ''

            if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
                # Generate client origin URI from the redirect_uri param.
                redirect_uri_parsed = urlsplit(self.params['redirect_uri'])
                client_origin = '{0}://{1}'.format(redirect_uri_parsed.scheme, redirect_uri_parsed.netloc)

                # Create random salt.
                salt = md5(uuid4().hex.encode()).hexdigest()

                # The generation of suitable Session State values is based
                # on a salted cryptographic hash of Client ID, origin URL,
                # and OP browser state.
                session_state = '{client_id} {origin} {browser_state} {salt}'.format(
                    client_id=self.client.client_id,
                    origin=client_origin,
                    browser_state=self.request.COOKIES['op_browser_state'],
                    salt=salt)
                session_state = sha256(session_state.encode('utf-8')).hexdigest()
                session_state += '.' + salt
                if self.grant_type == 'authorization_code':
                    query_params['session_state'] = session_state
                elif self.grant_type in ['implicit', 'hybrid']:
                    query_fragment['session_state'] = session_state

        except Exception as error:
            logger.debug('[Authorize] Error when trying to create response uri: %s', error)
            raise AuthorizeError(self.params['redirect_uri'], 'server_error', self.grant_type)

        uri = uri._replace(query=urlencode(query_params, doseq=True))
        uri = uri._replace(fragment=urlencode(query_fragment, doseq=True))

        return urlunsplit(uri)