I was evading the topic of security ever since I began posting my notes. It had a good reason: I’ve never worked with it. So I’d like to apologize here and now for the future mistakes in the following series of posts.
The first security-related objective we’ll revise is the accessing and modifying of the identity information. You can access the currently working user account (the entity under the current thread executes. There won’t be any calls to the stack to find an appropriate identity in it.). To achieve this, you’ll consider using two classes: the GenericIdentity and the GenericPrincipal classes. These classes have counterparts designed for using the Windows authentication services (like Active Directory). They are called WindowsIdentity and WindowsPrincipal respectively.
Of course, you can implement your custom Principal/Identity classes. In this case, your yet-to-come classes must implement IPrincipal or IIdentity. Let’s see a code sample on how to access the current user:
WindowsIdentity theIdentity = WindowsIdentity.GetCurrent();
Console.WriteLine(“Good news, you are authenticated!”);
GenericIdentity myCustomIdentity = new GenericIdentity(theIdentity.Name, theIdentity.AuthenticationType);
As you can see, retrieving the current Windows user is easy. If you’d like to cast it into a GenericIdentity, you should pass the user name, and the authentication type into its constructor.
Now back to the topic of identities and principals. Identities represent the current user who’s being validated, while principals represent the security context, under the code is executing. Lost, aren’t you? Check out the MSDN article.
Creating a GenericPrincipal won’t be the hardest task in your life. The constructor needs an Identity (any class that implements the IIdentity interface) and a string array of roles. It will be easy to provide one, based on the WindowsIdentity class:
WindowsIdentity wIden = WindowsIdentity.GetCurrent();
String roles = new String;
roles = “Authenticated”;
roles = “Guest”;
GenericPrincipal gP = new GenericPrincipal(wIden, roles);
You can set the current principal on a thread-basis by setting the Thread.CurrentPrincipal property to a class that implements IPrincipal. It would be something like this:
GenericIdentity gi = new GenericIdentity(“Name”, “NTLM”);
GenericPrincipal gp = new GenericPrincipal(gi, null);
System.Threading.Thread.CurrentPrincipal = gp;
Now we’ve got identities and principals, but what do they worth? Currently, nothing. But you can implement security checks in your code, and permit only execution to predefined users, with the PrincipalPermission class imperatively, or the PrincipalPermission attribute declaratively. These classes are defined in System.Security.Permissions. Let’s see how it works, assuming you’ve typed the code above:
PrincipalPermission pp = new PrincipalPermission(“Name”, null);
PrincipalPermission constructor accepts a name in string and a role in string. If you’ve changed the executing Principal into GenericPrincipal gp, the code above will execute. If not, it will throw a SecurityException. You can do the same thing with the PrincipalPermissionAttribute, the named parameters are the same as you can define in the PrincipalPermission class constructor.
Last but not least let’s examine the interfaces (IIdentity and IPrincipal) playing role in user security checks. IIdentity is very simple, it defines three read-only properties, string name, string authentication type and bool isauthenticated. I think there’s nothing to explain here.
IPrincipal isn’t the toughest interface you’ll come across. It has a Boolean method IsInRole, which takes a string parameter with the name of the role, and a read-only IIdentity property, which represents the Identity class under the current Principal.