【问题标题】:django oauth toolkit `or` in required scopes in viewdjango oauth 工具包“或”在所需范围内查看
【发布时间】:2021-06-25 22:04:35
【问题描述】:

我默认使用带有 IsAuthenticatedOrTokenHasScope 权限的 drf 和 oauth 工具包。我有一个包含范围的视图 required_scopes = ['mod', 'admin'] 当用户登录应用程序时,他有特殊的组来定义他的权限范围。所以当版主登录到应用程序时,他会得到mod 范围。当他调用我的视图时,他得到 403,因为 AccessToken 模型中的allow_scopes 返回 False。那是因为resource_scopes 是 ['mod', 'admin'] 而provided_scopes 是'mod'。当方法 allow_scopes 检查 resource_scopes.issubset(provided_scopes) 时,她返回 False,这在我的情况下不是故意的。

是否有任何其他选项不覆盖 AccessToken 模型中的 allow_scopes 来定义此视图需要范围 mod 或范围 admin。 ?

【问题讨论】:

    标签: python python-3.x django django-rest-framework django-oauth-toolkit


    【解决方案1】:

    我想我找到了一种方法来让它发挥作用。 oauth2_provider 没有提供任何功能来实现这一点。所以,我所做的是我定义了自己的自定义权限,类似于TokenHasScope。因此,创建一个名为 permissions.py 的文件并粘贴代码

    from rest_framework import permissions 
    from django.core.exceptions import ImproperlyConfigured
    from rest_framework.exceptions import PermissionDenied
    from oauth2_provider.settings import oauth2_settings
    
    class TokenHasAtLeastOneScope(permissions.BasePermission):
        """
        The request is authenticated as a user and the token used has at least one of the right scope
        """
    
        def has_permission(self, request, view):
            token = request.auth
    
            if not token:
                return False
    
            if hasattr(token, "scope"):  # OAuth 2
                required_scopes = self.get_scopes(request, view)
                log.debug("Required scopes to access resource: {0}".format(required_scopes))
    
                # If any scope in the list of required_scopes is valid, return True.
                for given_scope in required_scopes:
                    if token.is_valid([given_scope]):
                        return True
    
    
                # Provide information about required scope?
                include_required_scope = (
                    oauth2_settings.ERROR_RESPONSE_WITH_SCOPES
                    and required_scopes
                    and not token.is_expired()
                    and not token.allow_scopes(required_scopes)
                )
    
                if include_required_scope:
                    self.message = {
                        "detail": PermissionDenied.default_detail,
                        "required_scopes": list(required_scopes),
                    }
    
                return False
    
            assert False, (
                "TokenHasAtLeastOneScope requires the"
                "`oauth2_provider.rest_framework.OAuth2Authentication` authentication "
                "class to be used."
            )
    

    然后在您的视图中,导入权限并进行相应设置

    permission_classes = (permissions.TokenHasAtLeastOneScope)
    required_scopes = ['mod', 'admin']
    

    上面自定义的TokenHasAtLeastOneScope中,代码与TokenHasScope类似。唯一改变的行是

    for given_scope in required_scopes:
        if token.is_valid([given_scope]):
            return True
    

    循环遍历required_scopes 列表中的项目,如果找到有效范围,则返回 True。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 2020-06-26
      • 2015-01-19
      • 2012-06-15
      • 1970-01-01
      • 2017-04-01
      • 2014-04-02
      相关资源
      最近更新 更多