有人在部分信任场景中使用F#代码的经验吗?与中一样,使用[<AllowPartiallyTrustedCallers>]
创建程序集?
我正在做几个项目,我们需要能够在部分信任下运行,我们一直在尝试使用2级安全规则(http://msdn.microsoft.com/en-us/library/dd233102.aspx)。在实践中,对于我们的自包含程序集来说,这很容易——只需放置一个属性;但有时我们的程序集引用了没有注释并假定为"SecurityCritical"的第三方DLL。这就是它变得"有趣"的地方。
在过去的几天里,F#似乎出现了一个严重的问题。NET安全策略希望您在类型/方法引用或调用"SecurityCritical"代码时使用[<SecuritySafeCritical>]
对其进行注释,而这恰好是NuGet上的大多数代码,因为这是它的默认值。现在,在F#中,在您开始使用闭包之前,这是可以工作的。你不能做:
namespace Foo
open System.Security
[<assembly: AllowPartiallyTrustedCallers>]
[<assembly: SecurityRules(SecurityRuleSet.Level2)>]
do()
[<SecurityCritical>]
module C =
let get () = [ 1 .. 10 ]
[<SecuritySafeCritical>]
module M =
let foo () =
seq {
for i in 1 .. 10 do
yield!
C.get ()
|> Seq.filter (fun x -> x % 2 = 0)
}
此程序集未能通过SecAnnotate.exe
检查,因为F#编译器将闭包提升到一个单独的类型,该类型现在未用[<SecuritySafeCritical>]
进行注释,默认为Transparent,但引用了一些关键代码,这是一个错误。
这听起来像是一个小限制,但为了避免闭包并满足SecAnnotate约束,我花了很多小时修改代码。也许F#可以将安全属性传播到它创建的闭包类型?有没有其他简单的方法来解决我所缺少的问题?
您可以将SecurityCritical
应用为程序集级属性:
[<assembly: SecurityCritical>]
然而,一个更好的方法是,假设你只是在写一个"普通"F#程序集——也就是说,一个不做任何需要特殊安全性的事情的程序集(例如p/Invoke)——将替换:
[<assembly: AllowPartiallyTrustedCallers>]
带有
[<assembly: SecurityTransparent>]
SecurityTransparentAttribute的MSDN页面上写着:
指定程序集不能导致特权提升。
透明程序集可以从部分受信任的代码访问,并且不能公开对任何受保护资源或功能的访问。程序集中的代码不允许取消代码访问安全检查,并且不能导致权限提升。
F#3.0版本的FSharp.Core也出于同样的原因使用了这个属性。
附加信息链接:
- 当透明的反面不是不透明的
- 将代码标记为透明