【问题标题】:MSTEST PrincipalPermissionMSTEST PrincipalPermission
【发布时间】:2009-07-09 20:03:31
【问题描述】:

如何对带有 PrincipalPermission 属性的代码进行单元测试?

例如,这是有效的:

class Program
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        var c = new MyClass();
    }
}

[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Users")]
class MyClass
{
    public MyClass()
    {
        Console.WriteLine("This works.");
    }
}

这会引发 SecurityException:

[TestClass]
public class UnitTest1
{
    [TestInitialize]
    public void TestInitialize()
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
    }

    [TestMethod]
    public void TestMethod1() 
    { 
        var c = new MyClass();
    }
}

有什么想法吗?

【问题讨论】:

  • 有趣...我用 TestDriven 运行了相同的测试,它通过了。在这种情况下,测试似乎以我的身份运行,但是当使用 mstest 运行测试时,CurrentPrincipal 具有“空白”身份。有谁知道为什么?

标签: c# .net security unit-testing mstest


【解决方案1】:

如何创建一个GenericIdentity 并将其附加到您的测试中的Thread.CurrentPrincipal,如下所示:

[TestMethod]
public void TestMethod1() 
{ 
    var identity = new GenericIdentity("tester");
    var roles = new[] { @"BUILTIN\Users" };
    var principal = new GenericPrincipal(identity, roles);
    Thread.CurrentPrincipal = principal;

    var c = new MyClass();
}

对于失败的测试,您可以:

[TestMethod]
[ExpectedException(typeof(SecurityException))] // Or whatever it's called in MsTest
public void TestMethod1() 
{ 
    var identity = new GenericIdentity("tester");
    var roles = new[] { @"BUILTIN\NotUsers" };
    var principal = new GenericPrincipal(identity, roles);
    Thread.CurrentPrincipal = principal;

    var c = new MyClass();
}

【讨论】:

  • 这行得通,雷,谢谢!但这似乎太容易伪造了。不能有人声称拥有 require 角色吗?
  • 酷!乐意效劳!在完全信任的环境中就这么简单。设置 Thread.CurrentPrincipal 需要特殊的权限,具体来说,您需要 SecurityPermissionFlag.ControlPrincipal 的 SecurityPermission。在线查看 Keith Brown 的书:alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/…
  • 非常有趣的文章!但是我无法知道或控制我的用户是否具有更改 CurrentPrincipal 的安全权限。幸运的是,我的应用程序是一个 WCF 服务,我猜测(并希望)它不会传播 CurrentPrincipal。
  • 只是补充一点:在MsTest中,你可以将角色添加到主体,但是如果你不给身份一个有效的名字,那么它会认为它没有经过身份验证。抓了我大约一个小时,那个。
  • 那个虚拟的通用身份很重要:我试图变得聪明并使用Thread.CurrentPrincipal.Identity 来避免创建通用身份,但这在某些机器上失败了,因为出于某种原因,第一次测试运行时线程上没有有效身份!
【解决方案2】:

您可以在测试方法中尝试impersonating 不同的用户,如果您以管理员身份运行代码,您可以在测试(或测试类)中创建一个本地用户帐户并在最后删除它。

编辑:抱歉,我想象使用模拟来测试失败案例 - 我应该正确阅读您的问题 :) 我有类似的单元测试,他们能够在 mstest 中创建本地帐户。这是否是好的做法是另一回事。

我看到你已经按照this 页面的建议做了:将应用程序域的主体策略设置为“WindowsPrincipal”。对我来说,Thread.CurrentPrincipal.Identity.Name 给出了我的用户名,并且测试通过了针对 .NET 2.0、3.0 和 3.5 的 VS 2005 和 VS 2008。

您是否在带有 UAC 和非提升 VS 的 Vista/Win7 上运行?否则,您是否能够在另一台机器上使用不同的组或通过在您的机器上创建另一个本地管理员帐户并以该用户身份运行测试来重现?

【讨论】:

  • 当我运行测试时,CurrentPrincipal 有一个未经身份验证的 GenericIdentity,所以我不相信测试代码能够创建或删除本地帐户。
  • 我在 XP 上以管理员身份运行 VS。 Ray 的建议奏效了,但给我留下了其他安全问题。看看我离开 Ray 的 cmets。
猜你喜欢
  • 1970-01-01
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多