依赖项属性的安全性Dependency Property Security

依赖属性通常应当被视为公共属性。Dependency properties should generally be considered to be public properties. Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 属性系统在本质上无法对依赖属性值提供安全保证。The nature of the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) property system prevents the ability to make security guarantees about a dependency property value.

包装器和依赖属性的访问和安全性Access and Security of Wrappers and Dependency Properties

通常, 依赖属性是随 "包装器" 公共语言运行时 (CLR) 属性实现的, 这些属性可以简化从实例获取或设置属性的过程。Typically, dependency properties are implemented along with "wrapper" common language runtime (CLR) properties that simplify getting or setting the property from an instance. 但包装实际上只是一种简便方法, 可实现GetValueSetValue与依赖属性交互时使用的基础调用和静态调用。But the wrappers are really just convenience methods that implement the underlying GetValue and SetValue static calls that are used when interacting with dependency properties. 以另一种方式思考, 属性会作为公共语言运行时 (CLR) 属性公开, 而这些属性确实会由依赖属性 (而不是私有字段) 支持。Thinking of it in another way, the properties are exposed as common language runtime (CLR) properties that happen to be backed by a dependency property rather than by a private field. 应用于包装器的安全机制与属性系统行为以及基础依赖属性的访问并不可比。Security mechanisms applied to the wrappers do not parallel the property system behavior and access of the underlying dependency property. 在包装上放置安全要求仅会阻止使用便捷方法, 但不会阻止对GetValueSetValue的调用。Placing a security demand on the wrapper will only prevent the usage of the convenience method but will not prevent calls to GetValue or SetValue. 同样,为包装器设置受保护或私有访问级别也不会提供任何有效的安全性。Similarly, placing protected or private access level on the wrappers does not provide any effective security.

如果你正在编写自己的依赖项属性, 则应将该包装和DependencyProperty标识符字段声明为公共成员, 以便调用方不会获得有关该属性的 true 访问级别的误导性信息 (因为其存储正在作为依赖属性实现。If you are writing your own dependency properties, you should declare the wrappers and the DependencyProperty identifier field as public members, so that callers do not get misleading information about the true access level of that property (because of its store being implemented as a dependency property).

对于自定义依赖属性, 可以将属性注册为只读依赖属性, 这确实提供了一种有效的方法来防止不包含对该属性的DependencyPropertyKey引用的任何人设置属性。For a custom dependency property, you can register your property as a read-only dependency property, and this does provide an effective means of preventing a property being set by anyone that does not hold a reference to the DependencyPropertyKey for that property. 有关详细信息,请参阅只读依赖属性For more information, see Read-Only Dependency Properties.

备注

不禁止将标识符字段声明为私有的, 因此可以使用它来帮助减少自定义类的直接公开命名空间, 但在与公共语言相同的意义上, 此类属性不应被视为 "私有" DependencyProperty运行时 (CLR) 语言定义定义该访问级别, 原因如下部分所述。Declaring a DependencyProperty identifier field private is not forbidden, and it can conceivably be used to help reduce the immediately exposed namespace of a custom class, but such a property should not be considered "private" in the same sense as the common language runtime (CLR) language definitions define that access level, for reasons described in the next section.

依赖属性的属性系统公开Property System Exposure of Dependency Properties

这种方法通常并不有用, 它可能会产生误导性, DependencyProperty将声明为除 public 以外的任何访问级别。It is not generally useful, and it is potentially misleading, to declare a DependencyProperty as any access level other than public. 该访问级别设置只是防止某人从声明类获得对实例的引用。That access level setting only prevents someone from being able to get a reference to the instance from the declaring class. 但是, 属性系统有多个方面将返回DependencyProperty作为标识某个特定属性的方法, 因为该属性存在于类或派生类实例的实例上, 而此标识符仍可SetValue在调用中使用。如果将原始静态标识符声明为非公共标识符, 则为。But there are several aspects of the property system that will return a DependencyProperty as the means of identifying a particular property as it exists on an instance of a class or a derived class instance, and this identifier is still usable in a SetValue call even if the original static identifier is declared as nonpublic. 此外, OnPropertyChanged虚方法接收任何现有依赖属性的信息, 该属性更改了值。Also, OnPropertyChanged virtual methods receive information of any existing dependency property that changed value. 此外, 该GetLocalValueEnumerator方法为实例上具有本地设置值的任何属性返回标识符。In addition, the GetLocalValueEnumerator method returns identifiers for any property on instances with a locally set value.

验证和安全Validation and Security

将需求应用到ValidateValueCallback , 并预期在请求失败时验证失败, 以防止设置属性的安全机制。Applying a demand to a ValidateValueCallback and expecting the validation failure on a demand failure to prevent a property from being set is not an adequate security mechanism. 如果执行ValidateValueCallback的设置值无效, 则如果这些调用方在应用程序域中运行, 则它也会被恶意调用方抑制。Set-value invalidation enforced through ValidateValueCallback could also be suppressed by malicious callers, if those callers are operating within the application domain.

请参阅See also