2009-07-09 22 views
19

¿Cómo se decodifica el código de unidad de prueba con el atributo PrincipalPermission?MSTEST PrincipalPermission

Por ejemplo, esto funciona:

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."); 
    } 
} 

Esto arroja una SecurityException:

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

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

¿Alguna idea?

+0

interesante ... Me corrió la misma prueba con TestDriven y pasó. En este caso, la prueba pareció ejecutarse como yo, pero cuando la prueba se ejecutó con mstest, CurrentPrincipal tenía una identidad 'en blanco'. ¿Alguien sabe por qué? –

Respuesta

19

¿Qué hay de la creación de un GenericIdentity y adjuntar a la que Thread.CurrentPrincipal en su prueba de este modo:

[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(); 
} 

Para una prueba falla, usted podría:

[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(); 
} 
+0

Esto funcionó, Ray, gracias! Pero parecía demasiado fácil de falsificar. ¿Nadie podría decir que tiene el rol requerido? –

+0

¡Genial! ¡Encantado de ayudar! Es así de fácil en un entorno de plena confianza. Configurar Thread.CurrentPrincipal requiere privilegios especiales, específicamente, necesita SecurityPermission of SecurityPermissionFlag.ControlPrincipal. Vea el libro de Keith Brown en línea: http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsThreadDotCurrentPrincipal.html –

+0

¡Artículo muy interesante! Pero no tengo manera de saber o controlar si mis usuarios tienen permiso de seguridad para cambiar CurrentPrincipal o no. Afortunadamente, mi aplicación es un servicio de WCF que supongo (y espero), como el temporizador y el grupo de acción, no propagará el CurrentPrincipal. –

1

Puede probar impersonating diferentes usuarios dentro del método de prueba, si ejecuta el código como administrador puede crear una cuenta de usuario local dentro de la prueba (o clase de prueba) y eliminarla al final.

Editar: Lo siento, imaginé que usaría suplantar para probar un caso de falla - Debería haber leído su pregunta correctamente :) Tengo pruebas de unidad similares, y pueden crear cuentas locales dentro de mstest. Si esto es una buena práctica es otro asunto.

Veo que ya lo hizo como this la página sugiere: establecer la política principal del dominio de la aplicación en "WindowsPrincipal". Para mí, Thread.CurrentPrincipal.Identity.Name proporciona mi nombre de usuario y las pasadas de prueba utilizando VS 2005 y VS 2008 con orientación .NET 2.0, 3.0 & 3.5.

¿Se está ejecutando en Vista/Win7 con UAC y VS no elevados? De lo contrario, ¿puede reproducir en otra máquina, utilizar un grupo diferente o crear otra cuenta de administrador local en su máquina y ejecutar las pruebas como este usuario?

+0

Cuando ejecuto la prueba, CurrentPrincipal tiene una identidad genérica no autenticada, por lo que no creo que el código de prueba pueda crear o eliminar una cuenta local. –

+0

Estoy ejecutando VS en XP como administrador. La sugerencia de Ray funcionó, pero me dejó con otras preocupaciones de seguridad. Mira los comentarios que dejé Ray. –