This article has been
excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors
of C# Corner.
The System.Security.Principal namespace defines a principal object that
represents the security context under which code is running.
IIdentity Interface
- AuthenticationType: this property
returns a string that describes the type of authentication in place, such as
basic authentication, NTLM, Kerberos, or Passport. The value for this
property will be defined by each application.
- IsAuthenticated: this property
returns a value that indicates whether the current user has been
authenticated.
- Name: his property returns the user name
of the user represented by this identity.
IPrincipal Interface
- Identity: this property returns the
identity object that is associated with this principal.
- IsInRole: this method returns a
value that indicates whether the user represented by this principal belongs
to a specific role.
WindowsIdentity Class
The WindowsIndentity class implements the IIdentity interface. It represents the
identity of the user based on a method of authentication supported by the
Windows operating system. A Windows identity provides the ability to impersonate
another user so resources can be accessed on that user's behalf.
WindowsPrincipal Class
The WindowsPrincipal class implements the IPrincipal interface. It represents
Windows users and their roles, which are simply the Windows groups to which the
users belong.
GenericIdentity Class
The GenericIdentity class implements the IIdentity interface. It represents the
identity of the user based on a custom authentication method defined by the
application.
GenericPrincipal Class
The GenericPrincipal class implements the IPrincipal interface. It represents
users and roles that exist independent of Windows users and their roles.
Essentially, the generic principal is a simple solution for application
authentication and authorization.
PrincipalPermission Class
PrincipalPermission objects allow code to perform actions (Demand, Union,
Intersect, etc.) against the current user identity in a manner consistent with
the way those actions are performed for code access permissions and identity
permissions. PrincipalPermission can be issued as an imperative demand, as shown
at the top of Listing 22.27, or as a declarative demand, as the bottom of the
listing shows.
Listing 22.27: IsInRole Example
PrincipalPermission p = new PrincipalPermission(null,
"BUILTIN\Administrator");
p.Demand();
// or it can be issued as a declarative demand as shown in the line below
[PrincipalPermission(SecurityAction.Demand, Role=@"BUILTIN\Administrators")]
CurrentPrincipal Property
The CurrentPrincipal property of the Thread class is a static proprety that
allows you to get or set the current security context of the user. You can use
the CurrentPrincipal property of the System.Threading.Thread class in order to
get the current WindowsPrincipal object as in the line of code below:
WindowsPrincipal myWindowsPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
IsInRole Method
You can check role membership by calling the IsInRole method on the principal
object. You can use IsInRole with WindowsPrincipal and CurrentPrincipal. Listing
22.28 shows a simple use of the IsInRole method.
Listing 22.28: IsInRole Example
// IsInRole
WindowsPrincipal winpr = (WindowsPrincipal)Thread.CurrentPrincipal;
//
WindowsBuiltInRole is an enumeration!
// Is winpr object
in role of Administrator?
winpr.IsInRole(WindowsBuiltInRole.Administrator);
// Is the current
thread principal in role of Administrator?
System.Threading.Thread.CurrentPrincipal.IsInRole(@"BUILTIN\Administrator");
Impersonate and ImpersonateContext
If your application must impersonate a Windows account that has not been
attached to the current thread, you must retrieve that account's token and use
it to activate the account:
- Retrieve an account token for a particular
user by making a call to the unmanaged LogonUser method, passing it the user
name, password, and domain of the account you want. This method is not in
the .NET Framework base class library but is located in the unmanaged
advapi32.dll library. For the LogonUser call to work, a special privilege
known as SE_TCB_NAME is needed. You can check this by selecting Control
Panel?Administrative Tools?Local Security Policy Settings.
- Create a new instance of the
WindowsIdentity class, passing the account token retrieved in the preceding
step.
- Begin impersonation by creating a new
instance of the WindowsImpersonationContext class and initializing it with
the Impersonate method of the WindowsIdentity object created in the
preceding step.
- When you no longer need to impersonate the
Windows user, call the WindowsImpersonationContext.Undo method to revert the
impersonation with MyImpersonation.Undo();.
Listing 22.29 illustrates how you can
accomplish impersonation.
Listing 22.29: Impersonation Example
// impersonation
public
class
ImpersonationExample
{
[DllImport("ADVAPI32")]
private unsafe
static extern
int LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPasswords,
int dwLogonType,
int dwLogonProvider,
out InPtr phToken
);
public void
anyfunction()
{
InPtr lToken;
int lRetVal = 0;
lRetval = LogonUser(strUserName, strDomain,
strPassword, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, out lToken);
if (lRetval == 0)
{
Console.WriteLine("Login error
occurred!");
return;
}
WindowsIdentity ImpId = new
WindowsIdentity(lToken);
WindowsImpersonationContext ImpContext = ImpId.Impersonate();
// you are impersonating
another user now in this
// thread!
// execute some managed
and unmanaged code now
ImpContext.Undo();
}
}
Listing 22.30 creates two PrincipalPermission objects representing two different
users. The union demand succeeds only if user mcb is in the role of director or
user mindcracker is in the role of officer.
Listing 22.30: PrincipalPermission Union Example
// Union Demand
String id1 =
"mcb";
String role1 =
"Director";
PrincipalPermission PrincipalPerm1 = new
PrincipalPermission(id1, role1);
String id2 =
"mindcracker";
String role2 =
"Officer";
PrincipalPermission PrincipalPerm2 = new
PrincipalPermission(id2, role2);
(PrincipalPerm1.Union(PrincipalPerm2)).Demand();
In Listing 22.31, the current WindowsIdentity class is transformed into a
WindowsPrincipal class. Then all of the identity and principal properties are
written to the system console.
Listing 22.31: WindowsIdentity to WindowsPrincipal Example
// WindowsIdentity
illustrated
WindowsIdentity MyIdentity = WindowsIdentity.GetCurrent();
WindowsPrincipal MyPrincipal =
new WindowsPrincipal(MyIdentity);
//Principal values.
Console.WriteLine(MyPrincipal.Identity.Name);
Console.WriteLine(MyPrincipal.Identity.AuthenticationType);
Console.WriteLine(MyPrincipal.Identity.IsAuthenticated.ToString());
//Identity values.
Console.WriteLine(MyIdentity.Name);
Console.WriteLine(MyIdentity.AuthenticationType);
Console.WriteLine(MyIdentity.IsAuthenticated.ToString());
Console.WriteLine(MyIdentity.IsAnonymous.ToString());
Console.WriteLine(MyIdentity.IsGuest.ToString());
Console.WriteLine(MyIdentity.IsSystem.ToString());
Console.WriteLine(MyIdentity.Token.ToString());
Listing 22.32 illustrates GenericIdentity class usage.
Listing 22.32: GenericIdentity Example
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal myUser = WindowsPrincipal)System.Threading.Thread.CurrentPrincipal;
GenericIdentity MyIdentity = new
GenericIdentity(myUser.Identity.Name.ToString());
String[]
MyStringArray = {"Role1",
"Teller"};
GenericPrincipal MyPrincipal = new
GenericPrincipal(MyIdentity, MyStringArray);
System.Threading.Thread.CurrentPrincipal =
MyPrincipal;
//Return user values
String Name =
MyPrincipal.Identity.Name;
bool Auth =
MyPrincipal.Identity.IsAuthenticated;
bool IsInRole =
MyPrincipal.IsInRole("Role2");
if(IsInRole)
{
Console.WriteLine("The
test was successful as a user in the user-defined role of Role1");
}
else
{
Console.WriteLine("The
test was not successful!");
}
In Listing 22.33, declarative demands for PrincipalPermission and
PrincipalPermissionAttribute are illustrated. The attribute adjustment says that
only a principal in the role of Role1 may execute these functions.
Listing 22.33: Declarative Identity Example
[PrincipalPermission(SecurityAction.Demand, Role=@"Role1")]
private
string MyFunction()
{
return
"Declarative control for the role of
Role1 is truly successfully. his function can be executed by you!";
}
[PrincipalPermissionAttribute(SecurityAction.Demand, Name =
"MyUser", Role =
"Role1")]
public
static void
PrivateInfo()
{
//Output of private
data
Console.WriteLine("You
have access to the private data!");
}
Conclusion
Hope this article would have helped you in understanding
System.Security.Principal in .NET. See other articles on the website on .NET and C#.
|
The Complete Visual
C# Programmer's Guide covers most of the major components that make
up C# and the .net environment. The book is geared toward the
intermediate programmer, but contains enough material to satisfy the
advanced developer. |