Monday, July 16, 2007

Authenticating Users in Objective-C

Okay, so here is another solution. Let say you are creating an application that makes changes to your computer. You only want administrators to have the right to use your application. How do you go about doing this you might ask... Well, it is actually really simple. Here is how you access the built in authentication framework in Mac OS X in Objective-C.

First, you need to import some libraries. In the header file, import the following files:
  • Security/Authorization.h
  • Security/AuthorizationTags.h
Make sure you use the angle brackets instead of quotations.

This will give you access to the built in authentication and some variables to use for basic authentication.

Second, you need to declare some variables, you need the following:
  • OSStatus
  • AuthorizationRef
  • AuthorizationItem
  • AuthorizationRights
  • AuthorizationFlags
This is how I declared them in the demo app on the demo server. 

OSStatus status;
AuthorizationRef authorizationRef;
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0);
AuthorizationRights rightSet = { 1, &right };
AuthorizationFlags flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagDefaults;

Now, you have declared all the variables you will need. Notice that you don't have the '*' next to the variable name. This is because you are leaving the realm of Objective-C and going into C/C++ and Objective-C will try to create id variables for all the items with the '*'. This will cause the application to stop responding.

To check authorization, you need to do the two methods. 

First, call this method:

status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);

This calls the dialog to open if you aren't already authenticated. 
After this method call, call this

status = AuthorizationCopyRights(authorizationRef, &rightSet, kAuthorizationEmptyEnvironment, flags, NULL);

This will extract the actual authorization for the user entered and set it to the status variable.

Now, you do a check.

if (status == errAuthorizationSuccess){ 
//do something 

That's it! If the user is authenticated, then the method body will be executed, else, it is left alone. Now, in the demo app, I had problems getting the application to keep working after the user closed the dialog, or put in bad information. So, I just surrounded the code with a @try @catch block.

Happy coding! :-)

No comments: