September 19, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Implementing Simple Role-Based Security in Managed C++

  • October 18, 2002
  • By Kate Gregory
  • Send Email »
  • More Articles »

From Kate Gregory's Codeguru column, "Using Visual C++ .NET".

The .NET Framework makes things so much simpler for developers who care about security. There are a lot of useful ways to make sure that only authorized users update the database, place orders, or otherwise interact with your system. In addition, code access security ensures that only trusted code can perform certain tasks, no matter who runs the code.

In this column I focus only on one small topic: how to establish that the user running your application is authorized to perform some subtask within the application. You can extend the examples here to any application you write in Managed C++.

Who's There?

Here's a simple console application:

using namespace System;
using namespace System::Security::Principal;

// This is the entry point for this application
int _tmain(void)
{
    WindowsIdentity* Identity = WindowsIdentity::GetCurrent();
    WindowsPrincipal* Principal = new WindowsPrincipal(Identity);

    //Print the values.
    Console::WriteLine("Principal Values for current thread:");
    Console::WriteLine("Name: {0}", 
                       Principal->Identity->Name);
    Console::WriteLine("Type: {0}", 
                       Principal->Identity->AuthenticationType);
    Console::WriteLine("IsAuthenticated: {0}",
                       __box(Principal->Identity->IsAuthenticated));
    Console::WriteLine();
    Console::WriteLine();
    Console::WriteLine("Identity Values for current thread:");
    Console::WriteLine("Name: {0}", Identity->Name);
    Console::WriteLine("Type: {0}", Identity->AuthenticationType);
    Console::WriteLine("IsAuthenticated: {0}", 
                       __box(Identity->IsAuthenticated));
    Console::WriteLine("IsAnonymous: {0}", 
                       __box(Identity->IsAnonymous));
    Console::WriteLine("IsGuest: {0}", __box(Identity->IsGuest));
    Console::WriteLine("IsSystem: {0}", __box(Identity->IsSystem));
    Console::WriteLine("Token: {0}", Identity->Token.ToString());
    return 0;
}

The first line of this code gets the identity under which the application is running. That should be you, since the application doesn't contain any code to change the identity. Then it gets a principal based on that identity. The remainder of the code illustrates some useful properties of the identity and principal objects. Notice the use of __box to wrap up the Boolean values, and the ToString method to convert non-string values to strings.

When I run this application, it prints out:

Principal Values for current thread:
Name: GREGORY\kate
Type: NTLM
IsAuthenticated: True


Identity Values for current thread:
Name: GREGORY\kate
Type: NTLM
IsAuthenticated: True
IsAnonymous: False
IsGuest: False
IsSystem: False
Token: 304

You could do a little security code of your own at this point, comparing the name of the identity or principal with a list of names of authorized users that you have stored somewhere. But that will require you to write code to manage user lists: adding and deleting users, changing their authority code, and so on. I prefer to leverage Windows groups. Even if they aren't in use by the people who'll be running the application, it's less work to teach people to use Windows groups than to write your own equivalent administration section.

What Group Are You In?

This code checks to see if a user is in a particular Windows group or not:

String* role = "GREGORY\\Domain Users";
if (Principal->IsInRole(role))
    Console::WriteLine("You are a domain user");
else
    Console::WriteLine("You are not a domain user");

role = "BUILTIN\\Administrators";
if (Principal->IsInRole(role))
    Console::WriteLine("You are an administrator");
else
    Console::WriteLine("You are not an administrator");

role = "JSERV\\CodeGuru";
if (Principal->IsInRole(role))
    Console::WriteLine("You are a Code Guru");
else
    Console::WriteLine("You are not a Code Guru");

When I run this code, it prints out:

You are a domain user
You are an administrator
You are a Code Guru

For you, it almost certainly will not. Notice the three different prefixes in the role strings:

  • GREGORY is my domain. Use this prefix when you're referring to a group that has been created on your domain controller.

  • BUILTIN refers to built-in groups such as Administrators, created when you install Windows 2000 or NT.

  • JSERV is my machine name. Use this prefix when you're referring to a local group.

You can test this code by creating a local group, and adding yourself to it. If you've never done that before, you can use Computer Management. Right-click My Computer on your desktop and choose Manage. Expand the Local Users and Groups section, then click on Groups.



Click here for larger image

Choose Actions, New Group to create a group. Name it CodeGuru, and click Add to add users to it. Add yourself. Then log off Windows and log back on again to update your security profile, and run the application again. Now you should be told you are a Code Guru. (And don't forget about the logging off and logging on. You'll do a lot of that when you're testing security code.)

You could use tests of IsInRole() to decide whether to enable or disable a button. Or you could throw a security exception when the wrong kind of user tried to do something. If you'd like to do that, you're better off using permissions sets.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel