仅基于允许列表的授权系统
项目描述
django-denied
无人可进。
黑色骑士
django-denied 是 Django 网络框架的授权系统。使用 django-denied,Django 视图 必须显式允许。这种设计意味着开发者必须为视图的工作进行授权选择。
换句话说,django-denied 使得授权成为 Django 项目的每个视图的必需条件。
谁应该使用这个?
此包非常适合需要保护页面免受未经授权访问的 Django 项目。如果您正在开发需要用户登录并限制用户查看的数据的服务,那么 django-denied 可能适合您。
如果您的 Web 应用程序旨在对大量受众开放,特别是有很多匿名用户,那么此包可能超过了您的需求。博客或内容管理系统可能不是合适的选择。
安装
获取包。
pip install django-denied
django-denied 使用 Django 内置的 auth
和 admin
应用。这些应用还依赖于 contenttypes
应用。请确保这些应用已包含在您的 Django 设置文件中的 INSTALL_APPS
中。
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
...,
]
添加 DeniedMiddleware
。这个中间件负责所有的授权检查。中间件依赖于 request.user
,所以请确保在 AuthenticationMiddleware
之后再添加它。
MIDDLEWARE = [
...,
"django.contrib.auth.middleware.AuthenticationMiddleware",
"denied.middleware.DeniedMiddleware",
...,
]
现在你准备好了。
用法
django-denied有处理视图的两种主要模式。
允许
授权
这些装饰器是包的主要接口,下面将详细介绍。
默认情况下,django-denied假定所有用户都应该经过身份验证,除非是允许的视图或登录页面。
登录页面是
- 由
settings.LOGIN_URL
定义的页面,以及 - 在
admin:login
路由中定义的 Django 管理登录。
如果你设置了 LOGIN_URL
,django-denied期望的是设置的路径形式(例如,/accounts/login/
),而不是 url
名称(例如,accounts:login
)。
允许视图
每个应用都可能有一些应该对未经验证用户可访问的视图。一个公司的关于页面、服务条款和隐私政策都是很好的例子。
allow
装饰器用于标记 Django 视图,使其免于 DeniedMiddleware
执行的授权检查。
这是一个创建服务条款视图的示例。
# application/views.py
from denied.decorators import allow
from django.shortcuts import render
@allow
def terms_of_service(request):
return render(request, "tos.html", {})
allow
装饰器有一个次要功能。除了允许单个视图外,装饰器还可以允许一组视图,这可以使用 django.urls.path
。
这是为了允许第三方应用程序,这些应用程序有其他视图,但不知道 django-denied 系统。
这是一个使用 allow
允许 Django 管理视图以及流行的应用程序 django-allauth 的示例。
# project/urls.py
from denied.decorators import allow
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("accounts/", allow(include("allauth.urls"))),
path("admin/", allow(admin.site.urls)),
]
注意:即使你在视图或一组视图中包含了 allow
,这并不意味着你允许的内容会突然绕过现有的身份验证或授权检查。这是一个功能,而不是错误!
login_required
、permission_required
以及视图上现有的任何其他身份验证或授权检查都将保持不变。django-denied不会禁用其他第三方库的安全功能。
授权视图
使用 django-denied,Django 视图通过 authorize
装饰器和 授权器 函数进行授权。授权器的函数签名如下:
from django.http import HttpRequest
def example_authorizer(request: HttpRequest, **view_kwargs: dict) -> bool:
...
授权器评估传入的请求和视图信息,如果请求被授权则返回 True
,如果没有授权则返回 False
。view_kwargs
包含从 URL 路由解析出来的任何数据。
授权器充当声明性方式来显示对视图的授权。
from denied.decorators import authorize
from .authorizers import example_authorizer
@authorize(example_authorizer)
def example_view(request):
...
要在基于类的视图中使用 authorize
,你必须将装饰器附加到 dispatch
方法。
from denied.decorators import authorize
from django.utils.decorators import method_decorator
from django.views.generic import DetailView
from .authorizers import example_authorizer
from .models import Example
@method_decorator(authorize(example_authorizer), "dispatch")
class ExampleDetail(DetailView):
queryset = Example.objects.all()
内置授权器
库包含用于常见情况的内置授权器。
denied.authorizers.any_authorized
这个授权器始终评估为 True
,并且与 login_required
逻辑等价,因为 django-denied始终强制执行身份验证检查。
denied.authorizers.staff_authorized
这个授权器仅当 user.is_staff == True
时允许访问。staff_authorized
与 Django admin
应用中的 staff_member_required
等价。
授权器示例
本节将展示一个更完整的授权器示例,以帮助你了解 django-denied 在实际中的工作方式。
对于我们的示例,我们将考虑一个项目跟踪应用程序。这不过是一个将任务分组到项目中的 TODO 列表。
以下是模型。
# application/models.py
from django.contrib.auth.models import User
from django.db import models
class Project(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Task(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
description = models.TextField()
completed = models.BooleanField(default=False)
对于这个简单的系统,只有项目所有者可以对任务进行任何操作。让我们为这个创建一个授权器。
# application/authorizers.py
def task_authorized(request, **view_kwargs):
return Task.objects.filter(
project__owner=request.user,
pk=view_kwargs["pk"],
).exists()
这是我们想使用此授权器支持的 URL。
# application/urls.py
from django.urls import path
from .views import task_detail, task_edit
urlpatterns = [
path("tasks/<int:pk>/", task_detail, name="task_detail"),
path("tasks/<int:pk>/edit/", task_detail, name="task_edit"),
]
现在我们可以设置我们的视图并设置它们的授权。
# application/views.py
from denied.decorators import authorize
from django.shortcuts import render
from .authorizers import task_authorized
from .models import Task
@authorize(task_authorized)
def task_detail(request, pk):
task = Task.objects.get(pk=pk)
return render(request, "task_detail.html", {"task": task})
@authorize(task_authorized)
def task_edit(request, pk):
task = Task.objects.get(pk=pk)
return render(request, "task_edit.html", {"task": task})
由于授权者处理访问控制,我们可以确信仅通过其密钥即可安全地获取任务。将访问控制推到视图的边界,这样视图的内部逻辑就尽可能简单。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。
源分发
构建分发
django-denied-1.3.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 130da88b74984c36fd8deef44e5cec7b759828c514f1fffcb541a12b1c9f96fa |
|
MD5 | 3ee27510c2e9bf5c24a1e45e86e8ea7e |
|
BLAKE2b-256 | 4d5fe02af85f3369d7a569aca6f39956ed6273aabe9f80441232d561f6438b9e |
django_denied-1.3-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3fc870443097e6911cedca89d6d19c4aa8e4f10b7a02e2627e177ad60b880096 |
|
MD5 | bd6ad6a9a780530e7337362a694c0942 |
|
BLAKE2b-256 | ecbf0dbbbfdf63e999992331d6b0360c698be903040472ad51a445d72a8b0813 |