Python:TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制 [英] Python: TypeError: Pickling an AuthenticationString object is disallowed for security reasons

查看:134
本文介绍了Python:TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个类的对象(具有 multiprocessing ),并将其添加到 Manager.dict()中,以便可以从字典中删除该项目完成工作后,该对象(该项目所指向的对象)内部的对象.

我尝试了以下代码:

来自多处理导入管理器的

 ,流程类My_class(Process):def __init __():超级(My_class,self).__ init __()打印对象",自我,已创建".def运行(自己):打印对象",自我,过程已启动".manager = Manager()object_dict = manager.dict()对于范围(2)中的x:object_dict [x] = My_class()object_dict [x] .start() 

但是我遇到了一个错误:

  TypeError:不允许对AuthenticationString对象进行腌制出于安全原因 

出于好奇,我删除了多处理部分,并尝试如下操作:

来自多处理导入管理器的

 类My_class():def __init __():打印对象",自我创建".manager = Manager()object_dict = manager.dict()对于范围(2)中的x:object_dict [x] = My_class() 

它没有给我任何错误,并显示了两个对象的地址.

那是什么错误,以及如何解决?

解决方案

以下是复制您看到的效果的较短方法:

来自多处理导入过程的

 进口泡菜p = Process()pickle.dumps(p._config ['authkey']) 

TypeError:不允许对AuthenticationString对象进行腌制出于安全原因

这里实际发生的是以下内容: process._config ['authkey']

由于您不能腌制 AuthenticationString ,因此也不能腌制 Process 类或其任何子类的实例(因为它们都在字段中包含身份验证密钥)

现在,让我们看看它们与您的代码之间的关系.您创建一个 Manager 对象,并尝试设置其 dict 的值. Manager 实际上是在一个单独的进程中运行,每当您将任何数据分配给 manager.dict()时,Python都需要将该数据传输到 Manager的自己的过程.为了进行这种传输,需要对数据进行腌制.但是,从前几段我们知道,您不能使 Process 对象腌制,因此根本无法将它们保留在共享的 dict 中.

简而言之,您可以自由使用 manager.dict()共享任何对象,除了那些不能被腌制的对象,例如 Process 对象.

I'm creating an object of a class(with multiprocessing) and adding it to a Manager.dict() so that I can delete the item from the dictionary inside the object (the item points to) when its work completes..

I tried the following code:

from multiprocessing import Manager, Process

class My_class(Process):
    def __init__(self):
        super(My_class, self).__init__()
        print "Object", self, "created."

    def run(self):
        print "Object", self, "process started."


manager=Manager()
object_dict=manager.dict()

for x in range(2):
    object_dict[x]=My_class()
    object_dict[x].start()

But I got an error:

TypeError: Pickling an AuthenticationString object is disallowed
for security reasons

For curiosity, I removed the multiprocessing part, and tried like:

from multiprocessing import Manager
class My_class():
    def __init__(self):
        print "Object", self, "created."

manager=Manager()
object_dict=manager.dict()

for x in range(2):
    object_dict[x]=My_class()

and it's giving me no errors and displaying the addresses of two objects.

What's that error and how to make it go away?

解决方案

Here is a shorter way to replicate the effect you are seeing:

from multiprocessing import Process
import pickle

p = Process()
pickle.dumps(p._config['authkey'])

TypeError: Pickling an AuthenticationString object is disallowed for security reasons

What is actually happening here is the following: the process._config['authkey'] is the secret key that the Process object gets assigned on creation. Although this key is nothing more but a sequence of bytes, Python uses a special subclass of bytes to represent it: AuthenticationString. This subclass differs from the usual bytes in only one aspect - it refuses to be pickled.

The rationale behind this choice is the following: the authkey is used for authenticating inter-process communication messages between parent and child processes (e.g. between the workers and the main process) and exposing it anywhere outside the initial process family could pose a security risk (because you could, in principle, impersonate a "parent process" for the worker and force it into executing arbitrary code). As pickling is the most common form of data transfer in Python, prohibiting it is a simple way of an unintended exposure of the authkey.

As you cannot pickle an AuthenticationString, you also cannot pickle instances of Process class or any of its subclasses (because all of them contain an authentication key in a field).

Now let us take a look at how it all relates to your code. You create a Manager object and attempt to set the values of its dict. The Manager actually runs in a separate process and whenever you assign any data to manager.dict(), Python needs to transfer this data to the Manager's own process. For that transfer to happen, the data is being pickled. But, as we know from the previous paragraphs, you cannot pickle Process objects and hence cannot keep them in a shared dict at all.

In short, you are free to use manager.dict() to share any objects, except those which cannot be pickled, such as the Process objects.

这篇关于Python:TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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