如何有效地为部分信任创作F#程序集?

t0y*_*yv0 12 .net f# code-access-security

有没有人在部分信任场景中有F#代码的经验?如在,用[<AllowPartiallyTrustedCallers>]?创建程序集?

我正在开发一些我们需要能够以部分信任方式运行的项目,我们一直在尝试使用2级安全规则(http://msdn.microsoft.com/en-us/library/dd233102. aspx).在实践中,我们的自包含组件很容易 - 只需放置一个属性; 但有时我们的程序集会引用未注释并假定为"SecurityCritical"的第三方DLL.这是它"有趣"的地方.

经过几天的努力,F#似乎存在严重问题..NET安全策略要求您注释类型/方法,[<SecuritySafeCritical>]如果它们引用或调用"SecurityCritical"代码,这些代码恰好是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)
        }
Run Code Online (Sandbox Code Playgroud)

这个程序集无法通过SecAnnotate.exe检查,因为F#编译器将闭包提升到一个单独的类型,现在没有注释[<SecuritySafeCritical>],默认为Transparent,但引用了一些关键代码,这是一个错误.

这听起来像是一个小限制,但它花了我很多时间来改变代码以避免闭包并满足SecAnnotate约束.也许F#可以将安全属性传播给它创建的闭包类型?还有另一个简单的方法,我错过了吗?

Jac*_* P. 6

您可以应用SecurityCritical为程序集级属性:

[<assembly: SecurityCritical>]
Run Code Online (Sandbox Code Playgroud)

一个更好的方法,假设你只是编写一个"普通的"F#程序集 - 即一个没有做任何需要特殊安全性的程序(例如,P/Invoke) - 将取代:

[<assembly: AllowPartiallyTrustedCallers>]
Run Code Online (Sandbox Code Playgroud)

[<assembly: SecurityTransparent>]
Run Code Online (Sandbox Code Playgroud)

SecurityTransparentAttribute的MSDN页面说:

指定程序集不能导致权限提升.

可以从部分受信任的代码访问透明程序集,并且不能公开对任何受保护资源或功能的访问.程序集中的代码不允许禁止代码访问安全检查,也不会导致权限提升.

FSharp.Core的F#3.0版本也出于同样的原因使用此属性.

其他信息的链接: