Compartir a través de


Acceso directo a un objeto Principal

Actualización: noviembre 2007

Aunque la utilización de demandas imperativas y declarativas para invocar comprobaciones de seguridad basada en funciones es el mecanismo principal para comprobar y exigir la identidad y la pertenencia a una función, puede haber casos en los que se desee el acceso directo al objeto Principal y su objeto Identity asociado para realizar tareas de autorización sin crear objetos de permiso. Por ejemplo, puede que no desee utilizar demandas declarativas o imperativas si no desea que el hecho de que se produzca una excepción sea el comportamiento predeterminado en caso de producirse un error de validación. En este caso, puede utilizar la propiedad estática CurrentPrincipal en la clase System.Threading.Thread para tener acceso al objeto Principal y llamar a sus métodos.

Después de obtener el objeto principal, se pueden utilizar instrucciones condicionales para controlar el acceso al código basándose en su nombre, como se muestra en el ejemplo de código siguiente.

WindowsPrincipal MyPrincipal = 
    (WindowsPrincipal)Thread.CurrentPrincipal;
if (MyPrincipal.Identity.Name == "fred") 
    // Permit access to some code. 
Dim MyPrincipal As WindowsPrincipal = _
    CType(Thread.CurrentPrincipal, WindowsPrincipal)
If (MyPrincipal.Identity.Name = "fred") Then
    ' Permit access to some code.
End If

También se puede comprobar mediante programación la pertenencia a una función llamando al método IsInRole en el objeto Principal actual, como se muestra en el ejemplo de código siguiente.

// Get the current identity.
WindowsIdentity MyIdent = WindowsIdentity.GetCurrent();

// Create a principal.
WindowsPrincipal MyPrincipal = new WindowsPrincipal(MyIdent);

// Check the role using a string.
if (MyPrincipal.IsInRole(@"BUILTIN\Administrators"))
{
    Console.WriteLine("You are an administrator.");
}
else
{
    Console.WriteLine("You are not an administrator.");
}
// Check the role using an enumeration.
if (MyPrincipal.IsInRole(WindowsBuiltInRole.Administrator))
{
    Console.WriteLine("You are an administrator.");
}
else
{
    Console.WriteLine("You are not an administrator.");
}
' Get the current identity.
Dim MyIdent As WindowsIdentity = WindowsIdentity.GetCurrent()

' Create a principal.
Dim MyPrincipal As New WindowsPrincipal(MyIdent)

' Check the role using a string.
If MyPrincipal.IsInRole("BUILTIN\Administrators") Then
    Console.WriteLine("You are an administrator.")
Else
    Console.WriteLine("You are not an administrator.")
End If
' Check the role using an enumeration.
If MyPrincipal.IsInRole(WindowsBuiltInRole.Administrator) Then
    Console.WriteLine("You are an administrator.")
Else
    Console.WriteLine("You are not an administrator.")
End If

Se puede utilizar esta técnica cuando se desea el acceso a comportamientos específicos de un objeto Principal definido por la aplicación. Sin embargo, en la mayoría de los casos, se utiliza la clase PrincipalPermission para controlar el acceso al código basándose en la identidad o en la pertenencia a una función.

El siguiente ejemplo de código crea un objeto WindowsPrincipal y un objeto WindowsIdentity, los establece como el usuario actual y toma una decisión de seguridad basándose en el valor del objeto Principal. No utiliza un objeto PrincipalPermission de forma imperativa o declarativa, sino que toma una decisión de acceso basándose en los valores del objeto principal.

using System;
using System.Security.Permissions;
using System.Security.Policy;
using System.Security.Principal;
using System.Threading;

public class Class1
{
    public static int Main(string[] args)
    {
        // Set principal policy to get a WindowsPrincipal 
        // as the current principal so you have permission to get 
        // current user information.
        AppDomain.CurrentDomain.SetPrincipalPolicy(
            PrincipalPolicy.WindowsPrincipal);

        // Get the current principal and put it into a principal object.
        WindowsPrincipal myPrincipal = (Thread.CurrentPrincipal 
            as WindowsPrincipal);

        // Check the name and see if the user is authenticated. 
        if (myPrincipal.Identity.Name.Equals(@"MYDOMAIN\myuser") 
            && myPrincipal.Identity.IsAuthenticated.Equals(true))
        {
            Console.WriteLine("Hello {0}, you are authenticated!", 
                myPrincipal.Identity.Name.ToString());
        }
        else
        {
            Console.WriteLine("Go away! You are not authorized!");
        }
        // Use IsInRole to determine the role of the current user.
        Array wbirFields = Enum.GetValues(typeof(WindowsBuiltInRole));
        foreach (object roleName in wbirFields)
        {
            try
            {
                Console.WriteLine("{0}? {1}.", roleName,
                    myPrincipal.IsInRole((WindowsBuiltInRole)roleName));
            }
            catch (Exception)
            {
                Console.WriteLine("{0}: Could not obtain role for this RID.",
                    roleName);
            }
        }
        return 0;
    }
}  
Imports System
Imports System.Security.Permissions
Imports System.Security.Policy
Imports System.Security.Principal
Imports System.Threading

Public Class Class1

    Public Shared Sub Main()
        ' Set principal policy to get a WindowsPrincipal 
        ' as the current principal so you have permission to get
        ' current user information.
        AppDomain.CurrentDomain.SetPrincipalPolicy( _
            PrincipalPolicy.WindowsPrincipal)

        ' Get the current principal and put it into a principal object.
        Dim MyPrincipal As WindowsPrincipal = _
            CType(Thread.CurrentPrincipal, WindowsPrincipal)

        ' Check the name and see if the user is authenticated. 
        If (MyPrincipal.Identity.Name.Equals("MYDOMAIN\myuser") _
            And MyPrincipal.Identity.IsAuthenticated) Then
            Console.WriteLine("Hello {0}, you are authenticated!", _
                MyPrincipal.Identity.Name.ToString())
        Else
            Console.WriteLine("Go away! You are not authorized!")
        End If
        ' Use IsInRole to determine the role of the current user.
        Dim wbirFields As Array = _
            [Enum].GetValues(GetType(WindowsBuiltInRole))

        Dim roleName As Object
        For Each roleName In wbirFields
            Try
                Console.WriteLine("{0}? {1}.", roleName, _
                    MyPrincipal.IsInRole(CType(roleName, _
                    WindowsBuiltInRole)))
            Catch
                Console.WriteLine( _
                    "{0}: Could not obtain the role for this RID.", _
                    roleName)
            End Try
        Next roleName
    End Sub
End Class

Si el usuario actual es MYDOMAIN\myuser, este programa muestra el mensaje siguiente en la consola.

Hello MYDOMAIN\myuser, you are authenticated!

Sin embargo, si cualquier otro usuario es el usuario actual, el programa muestra el mensaje siguiente.

Go away! You are not authorized!

El valor de MyPrincipal.Identity.Name muestra el dominio y el nombre de usuario que representa la cuenta autorizada. Observe que en C# se antepone el signo arroba (@) a la cadena "MYDOMAIN\myuser" para que la barra diagonal inversa no se interprete como un carácter de escape. Aunque en el ejemplo anterior se utiliza un objeto WindowsIdentity, se puede crear fácilmente código similar utilizando un objeto genérico. Basta con crear una instancia del objeto genérico, pasarle los valores que se desee y comprobar posteriormente el objeto para esos valores.

Vea también

Conceptos

Comprobaciones de seguridad basada en funciones

Referencia

System.Threading.Thread.CurrentPrincipal