Directly Accessing a Principal Object
Although using imperative and declarative demands to invoke role-based security checks is the primary mechanism for checking and enforcing identity and role membership, there might be cases where you want to access the Principal object and its associated Identity object directly to do authorization tasks without creating permission objects. For example, you might not want to use declarative or imperative demands if you do not want a thrown exception to be the default behavior for validation failure. In this case, you can use the static CurrentPrincipal property on the System.Threading.Thread class to access the Principal object and call its methods.
After obtaining the principal object, you can use conditional statements to control access to your code based on the principal name as shown in the following code example.
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
You can also programmatically check role membership by calling the IsInRole method on the current Principal object as shown in the following code example.
// 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
You might use this technique when you want to access behaviors that are specific to an application-defined Principal object. However, in most cases, you use the PrincipalPermission class to control access to your code based on identity or role membership.
The following code example creates a WindowsPrincipal object and a WindowsIdentity object, sets them to the current user, and makes a security decision based on the value of the Principal. It does not use a PrincipalPermission object imperatively or declaratively, but makes an access decision based on the values of the principal object instead.
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
If the current user is MYDOMAIN\myuser, this program displays the following message to the console.
Hello MYDOMAIN\myuser, you are authenticated!
However, if any other user is the current user, the program displays the following message.
Go away! You are not authorized!
The value in MyPrincipal.Identity.Name shows the domain and user name that represents the authorized account. Notice that in C# the string "MYDOMAIN\myuser" is prefixed with the at sign (@) so that the backslash is not interpreted as an escape character. Although the previous example uses a WindowsIdentity object, you can easily produce similar code using a generic object. Simply create an instance of the generic object, pass it the values you want, and later check the object for those values.
See Also
Reference
System.Threading.Thread.CurrentPrincipal