授予“用户更改"权限时,如何防止 Django 管理员中的权限升级?允许? [英] How do I prevent permission escalation in Django admin when granting "user change" permission?

查看:32
本文介绍了授予“用户更改"权限时,如何防止 Django 管理员中的权限升级?允许?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个拥有庞大客户群的 django 站点.我想让我们的客户服务部门能够更改普通用户帐户,执行更改密码、电子邮件地址等操作.但是,如果我授予某人内置的 auth |用户 |可以更改用户 权限,他们可以在任何帐户上设置is_superuser 标志,包括他们自己的帐户.(!!!)

I have a django site with a large customer base. I would like to give our customer service department the ability to alter normal user accounts, doing things like changing passwords, email addresses, etc. However, if I grant someone the built-in auth | user | Can change user permission, they gain the ability to set the is_superuser flag on any account, including their own. (!!!)

为非超级用户员工删除此选项的最佳方法是什么?我确定它涉及子类化 django.contrib.auth.forms.UserChangeForm 并将其挂接到我已经自定义的 UserAdmin 对象中......不知何故.但是我找不到有关如何执行此操作的任何文档,而且我还不太了解内部原理.

What's the best way to remove this option for non-superuser staff? I'm sure it involves subclassing django.contrib.auth.forms.UserChangeForm and hooking it into my already-custom UserAdmin object... somehow. But I can't find any documentation on how to do this, and I don't yet understand the internals well enough.

推荐答案

他们能够在任何账户上设置 is_superuser 标志,包括他们自己的账户.(!!!)

they gain the ability to set the is_superuser flag on any account, including their own. (!!!)

不仅如此,他们还可以一一赋予自己任何权限,效果相同...

Not only this, they also gain the ability to give themselves any permissions one-by-one, same effect...

我确定它涉及子类化 django.contrib.auth.forms.UserChangeForm

I'm sure it involves subclassing django.contrib.auth.forms.UserChangeForm

嗯,不一定.你在django的admin更改页面看到的表单是由admin应用动态创建的,基于UserChangeForm,但是这个类几乎没有在username字段中添加正则表达式验证.

Well, not necessarily. The form you see in the change page of django's admin is dynamically created by the admin application, and based on UserChangeForm, but this class barely adds regex validation to the username field.

并将其连接到我已经自定义的 UserAdmin 对象中...

and hooking it into my already-custom UserAdmin object...

自定义UserAdmin 是这里的方法.基本上,您想将 fieldsets 属性更改为类似的内容:

A custom UserAdmin is the way to go here. Basically, you want to change the fieldsets property to something like that :

class MyUserAdmin(UserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        # Removing the permission part
        # (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        # Keeping the group parts? Ok, but they shouldn't be able to define
        # their own groups, up to you...
        (_('Groups'), {'fields': ('groups',)}),
    )

但这里的问题是此限制将适用于所有用户.如果这不是您想要的,您可以例如覆盖 change_view 以根据用户的权限进行不同的行为.代码片段:

But the problem here is that this restriction will apply to all users. If this is not what you want, you could for example override change_view to behave differently depending on the permission of the users. Code snippet :

class MyUserAdmin(UserAdmin):
    staff_fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        # No permissions
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        (_('Groups'), {'fields': ('groups',)}),
    )

    def change_view(self, request, *args, **kwargs):
        # for non-superuser
        if not request.user.is_superuser:
            try:
                self.fieldsets = self.staff_fieldsets
                response = super(MyUserAdmin, self).change_view(request, *args, **kwargs)
            finally:
                # Reset fieldsets to its original value
                self.fieldsets = UserAdmin.fieldsets
            return response
        else:
            return super(MyUserAdmin, self).change_view(request, *args, **kwargs)

这篇关于授予“用户更改"权限时,如何防止 Django 管理员中的权限升级?允许?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆