Ejemplo n.º 1
0
    def create_code_response_dic(self):
        token = create_token(user=self.code.user,
                             client=self.code.client,
                             scope=self.code.scope)

        if self.code.is_authentication:
            id_token_dic = create_id_token(
                user=self.code.user,
                aud=self.client.client_id,
                nonce=self.code.nonce,
                at_hash=token.at_hash,
                request=self.request,
                scope=self.params['scope'],
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # We don't need to store the code anymore.
        self.code.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, token.client),
        }

        return dic
Ejemplo n.º 2
0
    def create_refresh_response_dic(self):
        token = create_token(user=self.token.user,
                             client=self.token.client,
                             scope=self.token.scope)

        # If the Token has an id_token it's an Authentication request.
        if self.token.id_token:
            id_token_dic = create_id_token(
                user=self.token.user,
                aud=self.client.client_id,
                nonce=None,
                at_hash=token.at_hash,
                request=self.request,
                scope=self.params['scope'],
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # Forget the old token.
        self.token.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, self.token.client),
        }

        return dic
Ejemplo n.º 3
0
    def create_access_token_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.3

        token = create_token(
            self.user,
            self.client,
            self.params['scope'].split(' '))

        id_token_dic = create_id_token(
            token=token,
            user=self.user,
            aud=self.client.client_id,
            nonce='self.code.nonce',
            at_hash=token.at_hash,
            request=self.request,
            scope=token.scope,
        )

        token.id_token = id_token_dic
        token.save()

        return {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'token_type': 'bearer',
            'id_token': encode_id_token(id_token_dic, token.client),
        }
Ejemplo n.º 4
0
    def create_access_token_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.3

        token = create_token(self.user, self.client,
                             self.params['scope'].split(' '))

        id_token_dic = create_id_token(
            token=token,
            user=self.user,
            aud=self.client.client_id,
            nonce='self.code.nonce',
            at_hash=token.at_hash,
            request=self.request,
            scope=token.scope,
        )

        token.id_token = id_token_dic
        token.save()

        return {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'token_type': 'bearer',
            'id_token': encode_id_token(id_token_dic, token.client),
        }
Ejemplo n.º 5
0
    def create_code_response_dic(self):
        token = create_token(
            user=self.code.user,
            client=self.code.client,
            scope=self.code.scope)

        if self.code.is_authentication:
            id_token_dic = create_id_token(
                user=self.code.user,
                aud=self.client.client_id,
                nonce=self.code.nonce,
                at_hash=token.at_hash,
                request=self.request,
                scope=self.params['scope'],
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # We don't need to store the code anymore.
        self.code.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, token.client),
        }

        return dic
Ejemplo n.º 6
0
    def create_refresh_response_dic(self):
        token = create_token(
            user=self.token.user,
            client=self.token.client,
            scope=self.token.scope)

        # If the Token has an id_token it's an Authentication request.
        if self.token.id_token:
            id_token_dic = create_id_token(
                user=self.token.user,
                aud=self.client.client_id,
                nonce=None,
                at_hash=token.at_hash,
                request=self.request,
                scope=self.params['scope'],
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # Forget the old token.
        self.token.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, self.token.client),
        }

        return dic
 def test_redirects_when_aud_is_list(self):
     """Check with 'aud' containing a list of str."""
     query_params = {
         'post_logout_redirect_uri': self.LOGOUT_URL,
     }
     id_token_dic = create_id_token(
         user=self.user, aud=self.oidc_client.client_id)
     id_token_dic['aud'] = [id_token_dic['aud']]
     id_token = encode_id_token(id_token_dic, self.oidc_client)
     query_params['id_token_hint'] = id_token
     response = self.client.get(self.url, query_params)
     self.assertRedirects(
         response, self.LOGOUT_URL, fetch_redirect_response=False)
 def test_redirects_when_aud_is_list(self):
     """Check with 'aud' containing a list of str."""
     query_params = {
         'post_logout_redirect_uri': self.LOGOUT_URL,
     }
     token = create_token(self.user, self.oidc_client, [])
     id_token_dic = create_id_token(
         token=token, user=self.user, aud=self.oidc_client.client_id)
     id_token_dic['aud'] = [id_token_dic['aud']]
     id_token = encode_id_token(id_token_dic, self.oidc_client)
     query_params['id_token_hint'] = id_token
     response = self.client.get(self.url, query_params)
     self.assertRedirects(
         response, self.LOGOUT_URL, fetch_redirect_response=False)
Ejemplo n.º 9
0
    def test_redirects(self):
        query_params = {
            'post_logout_redirect_uri': self.LOGOUT_URL,
        }
        response = self.client.get(self.url, query_params)
        # With no id_token the OP MUST NOT redirect to the requested redirect_uri.
        self.assertRedirects(response, settings.get('LOGIN_URL'), fetch_redirect_response=False)

        id_token_dic = create_id_token(user=self.user, aud=self.oidc_client.client_id)
        id_token = encode_id_token(id_token_dic, self.oidc_client)

        query_params['id_token_hint'] = id_token

        response = self.client.get(self.url, query_params)
        self.assertRedirects(response, self.LOGOUT_URL, fetch_redirect_response=False)
Ejemplo n.º 10
0
def generate_api_token(api_scopes, token, request=None):
    assert api_scopes
    api = api_scopes[0].api
    audience = api.oidc_client.client_id
    req_scopes = api.required_scopes

    id_token = create_id_token(
        token, token.user, aud=audience, request=request, scope=req_scopes)

    payload = {}
    payload.update(id_token)
    payload.update(_get_api_authorization_claims(api_scopes))
    payload['exp'] = _get_api_token_expires_at(token)

    return encode_id_token(payload, api.oidc_client)
Ejemplo n.º 11
0
def generate_api_token(api_scopes, token, request=None):
    assert api_scopes
    api = api_scopes[0].api
    audience = api.oidc_client.client_id
    req_scopes = api.required_scopes

    id_token = create_id_token(token.user,
                               aud=audience,
                               request=request,
                               scope=req_scopes)

    payload = {}
    payload.update(id_token)
    payload.update(_get_api_authorization_claims(api_scopes))
    payload['exp'] = _get_api_token_expires_at(token)

    return encode_id_token(payload, api.oidc_client)
Ejemplo n.º 12
0
    def create_refresh_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-6

        scope_param = self.params['scope']
        scope = (scope_param.split(' ') if scope_param else self.token.scope)
        unauthorized_scopes = set(scope) - set(self.token.scope)
        if unauthorized_scopes:
            raise TokenError('invalid_scope')

        token = create_token(user=self.token.user,
                             client=self.token.client,
                             scope=scope,
                             ae=self.token.ae,
                             rid=self.token.rid)

        # If the Token has an id_token it's an Authentication request.
        if self.token.id_token:
            id_token_dic = create_id_token(user=self.token.user,
                                           aud=self.client.client_id,
                                           token=token,
                                           nonce=None,
                                           at_hash=token.at_hash,
                                           request=self.request,
                                           scope=token.scope,
                                           acr=self.token.id_token.get('acr'),
                                           amr=self.token.id_token.get('amr'))
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # Forget the old token.
        self.token.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, self.token.client),
        }

        return dic
Ejemplo n.º 13
0
    def create_refresh_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-6

        scope_param = self.params['scope']
        scope = (scope_param.split(' ') if scope_param else self.token.scope)
        unauthorized_scopes = set(scope) - set(self.token.scope)
        if unauthorized_scopes:
            raise TokenError('invalid_scope')

        token = create_token(
            user=self.token.user,
            client=self.token.client,
            scope=scope)

        # If the Token has an id_token it's an Authentication request.
        if self.token.id_token:
            id_token_dic = create_id_token(
                user=self.token.user,
                aud=self.client.client_id,
                token=token,
                nonce=None,
                at_hash=token.at_hash,
                request=self.request,
                scope=token.scope,
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # Forget the old token.
        self.token.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, self.token.client),
        }

        return dic
Ejemplo n.º 14
0
    def create_code_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.1

        refresh_token = create_refresh_token(
            user=self.code.user,
            client=self.code.client,
            scope=self.code.scope,
        )
        refresh_token.save()

        token = create_token_with_refresh_token(refresh_token=refresh_token, )

        if self.code.is_authentication:
            id_token_dic = create_id_token(
                user=self.code.user,
                aud=self.client.client_id,
                token=token,
                nonce=self.code.nonce,
                at_hash=token.at_hash,
                request=self.request,
                scope=token.scope,
            )
        else:
            id_token_dic = {}
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        # We don't need to store the code anymore.
        self.code.delete()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, token.client),
        }

        return dic
Ejemplo n.º 15
0
    def create_refresh_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-6

        scope_param = self.params['scope']
        scope = (scope_param.split(' ')
                 if scope_param else self.refresh_token.scope)
        unauthorized_scopes = set(scope) - set(self.refresh_token.scope)
        if unauthorized_scopes:
            raise TokenError('invalid_scope')

        # update refresh token scope
        self.refresh_token.scope = scope
        self.refresh_token.save()

        token = create_token_with_refresh_token(
            refresh_token=self.refresh_token, )

        # All refresh token grants are authentication flows.
        id_token_dic = create_id_token(
            user=self.refresh_token.user,
            aud=self.client.client_id,
            token=token,
            nonce=None,
            at_hash=token.at_hash,
            request=self.request,
            scope=token.scope,
        )
        token.id_token = id_token_dic

        # Store the token.
        token.save()

        dic = {
            'access_token': token.access_token,
            'refresh_token': token.refresh_token.refresh_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, token.client),
        }

        return dic
Ejemplo n.º 16
0
    def test_redirects_when_aud_is_str(self):
        query_params = {
            'post_logout_redirect_uri': self.LOGOUT_URL,
        }
        response = self.client.get(self.url, query_params)
        # With no id_token the OP MUST NOT redirect to the requested
        # redirect_uri.
        self.assertRedirects(response,
                             '/post-logout/',
                             fetch_redirect_response=False)

        token = create_token(self.user, self.oidc_client, [])
        id_token_dic = create_id_token(token=token,
                                       user=self.user,
                                       aud=self.oidc_client.client_id)
        id_token = encode_id_token(id_token_dic, self.oidc_client)

        query_params['id_token_hint'] = id_token

        response = self.client.get(self.url, query_params)
        self.assertRedirects(response,
                             self.LOGOUT_URL,
                             fetch_redirect_response=False)
    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)
Ejemplo n.º 18
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)
Ejemplo n.º 19
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)
Ejemplo n.º 20
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 ''

            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)