文章目录
一、权限管理的访问控制
一、权限管理的访问控制
权限管理,一般指控制用户的访问权限,使得用户可以访问而且只能访问自己被授权的资源,不能多也不能少。现在的软件系统里基本上都用到了权限管理,只是控制的粒度、层面和侧重点会有所不同,比较完善的权限管理包括四个方面的访问控制:
1.功能(最基础):以用户完成某一功能为准。如“添加用户”、“删除用户”
2.数据:比功能访问权限的控制粒度更小,如“管理员可看到比一般用户更多的信息”
3.时间:给访问权限添加时间控制,让访问的资源在某一时间段中可用。如”12306只能在7:00-23:00时间段内购票“
4.空间:给访问权限添加空间控制,根据访问用户的空间位置不同,而对用户的访问资源进行限制。如”很多人都在问,为什么在中国上不了facebook……“
二、RBAC设计理念
2.1.RBAC模型概述
RBAC模型(Role-Based Access Control:基于角色的访问控制)模型是20世纪90年代研究出来的一种新模型。RBAC认为权限授权的过程可以抽象地概括为:Who是否可以对What进行How的访问操作,并对这个逻辑表达式进行判断是否为True的求解过程
2.2 RBAC的组成
在RBAC模型里面,有3个基础组成部分,分别是:用户、角色和权限
RBAC通过定义角色的权限,并对用户授予某个角色从而来控制用户的权限,实现了用户和权限的逻辑分离(区别于ACL模型),极大地方便了权限的管理
下面在讲解之前,先介绍一些名词:
User(用户):每个用户都有唯一的UID识别,并被授予不同的角色
Role(角色):不同角色具有不同的权限
Permission(权限):访问权限
用户-角色映射:用户和角色之间的映射关系
角色-权限映射:角色和权限之间的映射
2.3 RBAC设计理念
RBAC的功能模块
RBAC数据库设计
二、Pyhton中RBAC的设计思路
1、数据库层面(models)
用户、角色、权限、权限组、菜单(菜单只是为了在页面展示以及菜单作用)
2、中间件层(middlewares)
中间件层是在用户请求服务器最前面的一层过滤系统,在rbac组件中它的作用是:
a、让未登录的用户无法访问相应的URL地址。 (用户登录之后 才能拥有特定权限,并且把相关权限格式化成字典格式 存入session)
b、把当前登录的用户权限和当前URL匹配 是否有权限,如果没有就返回404。
3、view视图层(view)
处理:路由系统分配的请求。
4、HTML层(前端页面显示)
三、代码
models.py
from django.db import models
class User(models.Model):
phone = models.CharField(verbose_name="手机号码", max_length=11)
user_name = models.CharField(verbose_name="姓名", max_length=30)
user_code = models.CharField(verbose_name="账号", max_length=30)
password = models.CharField(verbose_name="密码", max_length=30)
status_cd = models.CharField(verbose_name="状态", max_length=10)
create_date = models.DateTimeField(verbose_name="创建时间", max_length=30)
roles = models.ManyToManyField(verbose_name="拥有的所有角色", to='Role', blank=True)
def __str__(self):
return self.user_name
class Role(models.Model):
role_code = models.CharField(verbose_name="角色编码", max_length=30)
role_name = models.CharField(verbose_name="角色名称", max_length=50)
status_cd = models.CharField(verbose_name="状态", max_length=10)
create_date = models.DateTimeField(verbose_name="创建时间", max_length=30)
privileges = models.ManyToManyField(verbose_name="拥有的所有权限", to='Privilege', blank=True)
def __str__(self):
return self.role_name
class Privilege(models.Model):
pri_code = models.CharField(verbose_name="权限编码", max_length=30)
pri_name = models.CharField(verbose_name="权限名称", max_length=50)
is_menu = models.BooleanField(verbose_name="是否可以做菜单", default=False)
icon = models.CharField(verbose_name="图标", max_length=32, null=True, blank=True)
status_cd = models.CharField(verbose_name="状态", max_length=10)
create_date = models.DateTimeField(verbose_name="创建时间", max_length=30)
def __str__(self):
return self.pri_name
service 文件 init_privileges.py
from django.conf import settings
def init_privileges(current_user, request):
"""
用户权限的初始化
:param current_user: 当前用户对象
:param request: 请求相关所有数据
:return:
"""
# 2. 权限信息初始化
# 根据当前用户信息获取此用户所拥有的所有权限,并放入session。
# 当前用户所有权限
privileges_queryset = current_user.roles.filter(privileges__isnull=False).values('privileges__pri_code',
'privileges__pri_name').distinct()
privileges_list = [item['privileges__pri_code'] for item in privileges_queryset]
# for item in privileges_list:
# print(item)
request.session[settings.PERMISSION_SESSION_KEY] = privileges_list
middleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
from CustomerNetwork import settings
import re
class checkPermission(MiddlewareMixin):
def process_request(self, request):
'''
获取当前用户信息
获取所有权限
匹配
'''
current_url = request.path_info
permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
if not permission_dict:
return HttpResponse('无权限信息,请重新登录')
for url in permission_dict:
if re.match(current_url, url):
# print(current_url)
# print(url)
return HttpResponse("ok1")
# flag = False
views文件夹中.py
from django.shortcuts import render, HttpResponse
from rbac import models
from rbac.service.init_privilage import init_privileges
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
user_name = request.POST.get('user')
password = request.POST.get('pwd')
current_user = models.User.objects.filter(user_name=user_name, password=password).first() # 重复的第一个
if not current_user:
return render(request, 'login.html', {'msg': "用户名或密码错误"})
init_privileges(current_user, request)
return HttpResponse("ok")
template文件夹中html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="请输入用户名">
<input type="password" name="pwd" placeholder="请输入密码">
<input type="submit" value="提交"><span style="color: red">{{ msg }}</span>
</form>
</body>
</html>
settting.py
# 权限配置
PERMISSION_SESSION_KEY = "pri_session_key"
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'webboss.md.middleware.checkPermission'
]