Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于值组合的安全散列密钥_Python_Mongodb_Pymongo - Fatal编程技术网

Python 基于值组合的安全散列密钥

Python 基于值组合的安全散列密钥,python,mongodb,pymongo,Python,Mongodb,Pymongo,我在MongoDB中有大量记录/文档,我需要通过每个文档列表中的值组合来限制对项目的访问 想象一下,安全性可能的单个值是[1,2,3] 一个记录可以包含以下内容的任意组合: (1,)(2,)(3,)(1,2)(1,3)(2,3)(1,2,3) 有权访问[1]的用户只能看到具有()和(1)的记录 有权访问[2]的用户只能看到具有()和(2)的记录 有权访问[1,2]的用户将只能看到具有(),(1),(2),(1,2)的记录 只有能够访问[1,2,3]的用户才能查看所有记录 现在,在数据库的入口

我在MongoDB中有大量记录/文档,我需要通过每个文档列表中的值组合来限制对项目的访问

想象一下,安全性可能的单个值是[1,2,3]

一个记录可以包含以下内容的任意组合: (1,)(2,)(3,)(1,2)(1,3)(2,3)(1,2,3)

  • 有权访问[1]的用户只能看到具有()和(1)的记录
  • 有权访问[2]的用户只能看到具有()和(2)的记录
  • 有权访问[1,2]的用户将只能看到具有(),(1),(2),(1,2)的记录
  • 只有能够访问[1,2,3]的用户才能查看所有记录
现在,在数据库的入口点,我知道了用户的访问权限,例如[1,2,3]。但是我不能很容易地(特别是索引)通过查看记录来检索用户可以访问的所有值

创建一个函数来为每个记录生成唯一的哈希,这将非常容易:

def hash_combination(input):
    return hash(frozenset(input))
这将为每个记录提供一个唯一的键,我们可以将其作为过滤器索引使用。然后,为用户获取所有可能的密钥也很容易:

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))

def hash_powerset(iterable):
    return [hash(frozenset(x)) for x in powerset(iterable)]
但是,组合可能的唯一输入的实际列表可能相当大(50+),这造成了一个太大而不实用的因素

我只能想到两种可能的解决办法。第一是逐行检查:

security_list = (1, 2, 3)
for row in db.collection.find():
    # check security
    if any(x not in security_list for x in row['row_security']):
        continue
    # security passed
    pass
但这是一个相当高的性能杀手。另一个是将选择反转为“我们看不见的东西”:

但这也是mongodb无法索引的操作(可能是因为与我现在遇到的类似的原因),因此性能仍然不好。比前面的选项更好(因为您避免了将python对象转换为瓶颈),但仍然不是很好

我们案例的一些细节:

  • 我们总是知道用户的安全列表
  • 我们总是知道唯一的可能值列表(这可能很大)
  • python 2.7、mongodb 3.0
还有其他方法吗?最好的方法是什么

亲切问候,


Carst

根据Python Zen,您首先要发明一个干净的解决方案,只有当您真正看到它需要优化时,才着手对其进行优化

如你所见,这里实际上有两个任务:1)制定一个通用算法,2)针对特定环境优化算法


您任务的核心是:

  • 鉴于:

    • 每个记录都有一组标记(1,2,3),标记访问它所需的“特权/许可级别”
    • 用户也有一组相同的标志,指定其清除级别
  • 问题:

    • 返回用户有权访问的所有记录
现在它是这样表述的,答案很简单:

result = {record for record in set_ if user.mask >= record.mask}


现在,对于第二个任务,您需要检查MongoDB有效地执行了哪些操作,并找出如何使用它们来实现此操作。

对于代码审查来说,这似乎是一个很好的问题()老实说,我发现有时很难选择哪一个是最好的。但是我基于它指出stackoverflow是“一个特定的编程问题,或者一个软件算法”,我想这是你发明的系统的正确名称。嗨,完全同意Python Zen,我必须强调,我给出的两个解决方案在功能上都是有效的。第一个解决方案基本上是您建议的真实mongodb版本。我必须说,我的问题的标题可能会更好。问题是:算法类型和掩码的包含/排除方法在这里非常重要,这就是为什么我在每次解决方案之后都会深入到性能部分。这使得两种理论上的功能性解决方案在实用上都不可行:/
result = {record for record in set_ if user.mask >= record.mask}