如何有效地为部分信任编写F#程序集



有人在部分信任场景中使用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也出于同样的原因使用了这个属性。

附加信息链接:

  • 当透明的反面不是不透明的
  • 将代码标记为透明

最新更新