Пример #1
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
Пример #2
0
    def validate_params(self):

        if self.params['grant_type'] == 'refresh_token':
            if not self.params['refresh_token']:
                logger.debug('[Token] Missing refresh token')
                raise TokenError('invalid_grant')

            try:
                self.token = Token.objects.get(
                    refresh_token=self.params['refresh_token'])

            except Token.DoesNotExist:
                logger.debug('[Token] Refresh token does not exist: %s',
                             self.params['refresh_token'])
                raise TokenError('invalid_refresh_token')
            if self.token.token_refresh_has_expired():
                logger.debug('[Token] Token Refresh has expired: %s',
                             self.params['refresh_token'])
                raise TokenError('expired_refresh_token')
        else:
            logger.debug('[Token] Invalid grant type: %s',
                         self.params['grant_type'])
            raise TokenError('unsupported_grant_type')
Пример #3
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
Пример #4
0
 def validate_requested_scopes(self):
     """
     Handling validation of requested scope for grant_type=[password|client_credentials]
     """
     token_scopes = []
     if self.params['scope']:
         # See https://tools.ietf.org/html/rfc6749#section-3.3
         # The value of the scope parameter is expressed
         # as a list of space-delimited, case-sensitive strings
         for scope_requested in self.params['scope'].split(' '):
             if scope_requested in self.client.scope:
                 token_scopes.append(scope_requested)
             else:
                 logger.debug('[Token] The request scope %s is not supported by client %s',
                              scope_requested, self.client.client_id)
                 raise TokenError('invalid_scope')
     # if no scopes requested assign client's scopes
     else:
         token_scopes.extend(self.client.scope)
     return token_scopes
Пример #5
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
Пример #6
0
    def validate_params(self):
        try:
            self.client = Client.objects.get(
                client_id=self.params['client_id'])
        except Client.DoesNotExist:
            logger.debug('[Token] Client does not exist: %s',
                         self.params['client_id'])
            raise TokenError('invalid_client')

        if self.client.client_type == 'confidential':
            if not (self.client.client_secret == self.params['client_secret']):
                logger.debug(
                    '[Token] Invalid client secret: client %s do not have secret %s',
                    self.client.client_id, self.client.client_secret)
                raise TokenError('invalid_client')

        if self.params['grant_type'] == 'authorization_code':
            if not (self.params['redirect_uri'] in self.client.redirect_uris):
                logger.debug('[Token] Invalid redirect uri: %s',
                             self.params['redirect_uri'])
                raise TokenError('invalid_client')

            try:
                self.code = Code.objects.get(code=self.params['code'])
            except Code.DoesNotExist:
                logger.debug('[Token] Code does not exist: %s',
                             self.params['code'])
                raise TokenError('invalid_grant')

            if not (self.code.client == self.client) \
               or self.code.has_expired():
                logger.debug(
                    '[Token] Invalid code: invalid client or code has expired')
                raise TokenError('invalid_grant')

            # Validate PKCE parameters.
            if self.params['code_verifier']:
                if self.code.code_challenge_method == 'S256':
                    new_code_challenge = urlsafe_b64encode(
                        hashlib.sha256(self.params['code_verifier'].encode(
                            'ascii')).digest()).decode('utf-8').replace(
                                '=', '')
                else:
                    new_code_challenge = self.params['code_verifier']

                # TODO: We should explain the error.
                if not (new_code_challenge == self.code.code_challenge):
                    raise TokenError('invalid_grant')

        elif self.params['grant_type'] == 'password':
            if not settings.get('OIDC_GRANT_TYPE_PASSWORD_ENABLE'):
                raise TokenError('unsupported_grant_type')

            auth_args = (self.request, )
            try:
                inspect.getcallargs(authenticate, *auth_args)
            except TypeError:
                auth_args = ()

            user = authenticate(*auth_args,
                                username=self.params['username'],
                                password=self.params['password'])

            if not user:
                raise UserAuthError()

            self.user = user

        elif self.params['grant_type'] == 'refresh_token':
            if not self.params['refresh_token']:
                logger.debug('[Token] Missing refresh token')
                raise TokenError('invalid_grant')

            try:
                self.token = Token.objects.get(
                    refresh_token=self.params['refresh_token'],
                    client=self.client)

            except Token.DoesNotExist:
                logger.debug('[Token] Refresh token does not exist: %s',
                             self.params['refresh_token'])
                raise TokenError('invalid_grant')
        elif self.params['grant_type'] == 'client_credentials':
            if not self.client._scope:
                logger.debug(
                    '[Token] Client using client credentials with empty scope')
                raise TokenError('invalid_scope')
        else:
            logger.debug('[Token] Invalid grant type: %s',
                         self.params['grant_type'])
            raise TokenError('unsupported_grant_type')
Пример #7
0
    def validate_params(self):
        try:
            self.client = Client.objects.get(
                client_id=self.params['client_id'])
        except Client.DoesNotExist:
            logger.debug('[Token] Client does not exist: %s',
                         self.params['client_id'])
            raise TokenError('invalid_client')

        if self.client.client_type == 'confidential':
            if not (self.client.client_secret == self.params['client_secret']):
                logger.debug(
                    '[Token] Invalid client secret: client %s do not have secret %s',
                    self.client.client_id, self.client.client_secret)
                raise TokenError('invalid_client')

        if self.params['grant_type'] == 'authorization_code':
            if not (self.params['redirect_uri'] in self.client.redirect_uris):
                logger.debug('[Token] Invalid redirect uri: %s',
                             self.params['redirect_uri'])
                raise TokenError('invalid_client')

            try:
                self.code = Code.objects.get(code=self.params['code'])
            except Code.DoesNotExist:
                logger.debug('[Token] Code does not exist: %s',
                             self.params['code'])
                raise TokenError('invalid_grant')

            if not (self.code.client == self.client) \
               or self.code.has_expired():
                logger.debug(
                    '[Token] Invalid code: invalid client or code has expired',
                    self.params['redirect_uri'])
                raise TokenError('invalid_grant')

            # Validate PKCE parameters.
            if self.params['code_verifier']:
                if self.code.code_challenge_method == 'S256':
                    new_code_challenge = urlsafe_b64encode(
                        hashlib.sha256(self.params['code_verifier'].encode(
                            'ascii')).digest()).decode('utf-8').replace(
                                '=', '')
                else:
                    new_code_challenge = self.params['code_verifier']

                # TODO: We should explain the error.
                if not (new_code_challenge == self.code.code_challenge):
                    raise TokenError('invalid_grant')

        elif self.params['grant_type'] == 'refresh_token':
            if not self.params['refresh_token']:
                logger.debug('[Token] Missing refresh token')
                raise TokenError('invalid_grant')

            try:
                self.token = Token.objects.get(
                    refresh_token=self.params['refresh_token'],
                    client=self.client)

            except Token.DoesNotExist:
                logger.debug('[Token] Refresh token does not exist: %s',
                             self.params['refresh_token'])
                raise TokenError('invalid_grant')

        else:
            logger.debug('[Token] Invalid grant type: %s',
                         self.params['grant_type'])
            raise TokenError('unsupported_grant_type')