예제 #1
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),
        }
    def _create_token(self, extra_scope=None):
        """
        Generate a valid token.
        """
        if extra_scope is None:
            extra_scope = []
        scope = ['openid', 'email'] + extra_scope

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

        id_token_dic = create_id_token(
            token=token,
            user=self.user,
            aud=self.client.client_id,
            nonce=FAKE_NONCE,
            scope=scope,
        )

        token.id_token = id_token_dic
        token.save()

        return token
예제 #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),
        }
예제 #4
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
예제 #5
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
예제 #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
예제 #7
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=None, client=self.token.client, scope=scope)

        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'),
            'scope': self.token.client._scope,
        }

        return dic
예제 #8
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
예제 #9
0
 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)
예제 #10
0
    def create_client_credentials_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.4.3
        token_scopes = self.validate_requested_scopes()

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

        token.save()

        return {
            'access_token': token.access_token,
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'token_type': 'bearer',
            'scope': ' '.join(token.scope),
        }
예제 #11
0
    def _create_token(self, extra_scope=[]):
        """
        Generate a valid token.
        """
        id_token_dic = create_id_token(self.user,
                                       self.client.client_id, FAKE_NONCE)

        token = create_token(
            user=self.user,
            client=self.client,
            id_token_dic=id_token_dic,
            scope=['openid', 'email'] + extra_scope)
        token.save()

        return token
예제 #12
0
def create_oidc_token(oidc_client, admin_user, request):
    scope = ['openid', 'email']

    token = create_token(user=admin_user, client=oidc_client, scope=scope)

    id_token_dic = create_id_token(token=token,
                                   user=admin_user,
                                   aud=oidc_client.client_id,
                                   nonce='abcdefghijk',
                                   scope=scope,
                                   request=request)

    token.id_token = id_token_dic
    token.save()

    return token
예제 #13
0
    def _create_token(self, user, client, request):
        scope = ['openid', 'email']

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

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

        token.id_token = id_token_dic
        token.save()

        return token
예제 #14
0
    def create_client_credentials_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.4.3

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

        token.save()

        return {
            'access_token': token.access_token,
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'token_type': 'bearer',
            'scope': self.client._scope,
        }
예제 #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.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
예제 #16
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
예제 #17
0
 def test_create_id_token(self):
     start_time = int(time.time())
     login_timestamp = start_time - 1234
     self.user.last_login = timestamp_to_datetime(login_timestamp)
     client = create_fake_client("code")
     token = create_token(self.user, client, [])
     id_token_data = create_id_token(token=token, user=self.user, aud='test-aud')
     iat = id_token_data['iat']
     self.assertEqual(type(iat), int)
     self.assertGreaterEqual(iat, start_time)
     self.assertLessEqual(iat - start_time, 5)  # Can't take more than 5 s
     self.assertEqual(id_token_data, {
         'aud': 'test-aud',
         'auth_time': login_timestamp,
         'exp': iat + 600,
         'iat': iat,
         'iss': 'http://localhost:8000/openid',
         'sub': str(self.user.id),
     })
    def _create_token(self, extra_scope=[]):
        """
        Generate a valid token.
        """
        scope = ['openid', 'email'] + extra_scope

        id_token_dic = create_id_token(
            user=self.user,
            aud=self.client.client_id,
            nonce=FAKE_NONCE,
            scope=scope,
        )

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

        return token
예제 #19
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, settings.get('OIDC_LOGIN_URL'),
            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_token(self, extra_scope=None):
        """
        Generate a valid token.
        """
        if extra_scope is None:
            extra_scope = []
        scope = ['openid', 'email'] + extra_scope

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

        id_token_dic = create_id_token(
            token=token,
            user=self.user,
            aud=self.client.client_id,
            nonce=FAKE_NONCE,
            scope=scope,
        )

        token.id_token = id_token_dic
        token.save()

        return token
예제 #21
0
    def create_code_response_dic(self):
        # See https://tools.ietf.org/html/rfc6749#section-4.1

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

        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,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': encode_id_token(id_token_dic, token.client),
        }

        return dic
예제 #22
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)
예제 #23
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)
    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)
예제 #25
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)