Authority Issues II: The Dialog That Wouldn’t Die

Last time around, I talked about the Security framework. It is a set of “beneath the hood” C-based APIs you can use from Carbon or Cocoa.

In addition, there’s the Security Interface framework, which is a Cocoa framework of standard security UI widgets.

One of the widgets in this framework is the SFAuthorizationView, which looks like so in its unauthorized and authorized states:
SFAuthorizationView, locked iconSFAuthorizationView, unlocked icon

You tell it which right you want it to use, and it manages an AuthorizationRef for that right. It’s a very useful widget, but it has a gotcha.

You add an SFAuthorizationView to a window in your nib file by doing the following:

1) Drag the SecurityInterface/SFAuthorizationView.h header to your nib.

2) Make a custom view.

3) Change that custom view’s custom class to SFAuthorizationView.

Here’s some code for a delegate class for such a window. It assumes the delegate has an SFAuthorizationView outlet called “authorizationView”:

- (void)awakeFromNib
{
   [authorizationView setString:"right.to.party"];
   [authorizationView updateStatus:self];

   [authorizationView setFlags:
      kAuthorizationFlagInteractionAllowed |
      kAuthorizationFlagExtendRights];

   [authorizationView setAutoupdate:YES];
}

The first two messages are necessary to set up the authorization view. Without a specified right, the view can’t function. Without the updateStatus: message, it won’t show the lock icon correctly.

You’ll notice that the value for the setFlags: message is the same value I used for the second AuthoriaztionCreate)() function call in my last post. It serves the same purpose here that it did there.

But it’s the last call that’s the gotcha. You send the message setAutoupdate:YES if you want the authorization view to automatically change its appearance and behavior when, for example, an authorization expires, which they normally do after 5 minutes. So far so good.

But if that is combined with the flag kAuthorizationFlagInteractionAllowed, and if a user decides to cancel out of an authorization dialog instead of typing in a valid password…the then dialog comes back. Cancel it again, it comes back again. If you don’t have the password — say, for example, you’re not an adminstrative user for the Mac in question — the only way to get the dialog-that-won’t-die to go away is to force-quit the entire application.

Not good. There are two workarounds for this gotcha:

1) Don’t use kAuthorizationFlagInteractionAllowed. This means that when an update occurs, for example an authorization times out, the user won’t be prompted to authorize again immediately. Instead, the lock icon will just go ahead and lock itself. There isn’t a “nyah nyah” sound, but there might as well be.

2) Don’t set your view to autoupdate. You might do this if you’re using a right that, say, never expires.

For anyone using or thinking of using the SFAuthorizationView widget, I hope this helps.