如何验证帐户的密码

时间:2013-11-15 13:17:14

标签: objective-c macos

我在我的应用程序中询问帐户的密码(在mac中登录的密码)。如何验证输入用户的密码?

我认为类似的东西,但它不起作用:

-(BOOL)authenticatePassword:(char *)password adminName:(char *)userName
{

    BOOL retValue = NO;

    OSStatus status,status1;
    AuthorizationFlags flag;
    AuthorizationItem items[2];
    items[0].name = kAuthorizationEnvironmentPassword;
    items[0].value = password;
    items[0].valueLength = strlen(password);
    items[0].flags = 0;

    items[1].name = kAuthorizationEnvironmentUsername;
    items[1].value = userName;
    items[1].valueLength = strlen(userName);
    items[1].flags = 0;

    AuthorizationItemSet itemSet = {2,items};
    status = AuthorizationCreate(NULL, &itemSet, kAuthorizationFlagDefaults, &authorization_);
    if(status == errAuthorizationSuccess) {
        AuthorizationRights rights = {2,&items};
        //AuthorizationEnvironment kEnviroment = {2, items};
        AuthorizationFlags flag1 = kAuthorizationFlagDefaults;
        status1 = AuthorizationCopyRights(authorization_, &rights,NULL, flag1, NULL);

        if(status1 == errAuthorizationSuccess) {
            retValue = YES;
        }
    }

    return retValue;

}

3 个答案:

答案 0 :(得分:1)

AuthorizationCopyRights调用中,验证的用户凭据应该在environment参数(注释掉的行)中,而权限参数确实应该包含您希望使用此用户凭据获得的权限。

权限可以包含内置权限或用户创建的权限,使用内置权限更简单,因为创建用户定义的权限需要管理员权限。

此代码将为您提供帮助,只需使用用户名/密码参数调用AuthenticateForRight,它就会尝试获取允许权限,该权利是内置的authorizationDB并且需要有效的用户凭证。

要使用自定义权限,您应该使用管理员权限调用SetupAuthorizationForRight,然后在authenticationDB中创建权限,之后您可以通过AuthenticateForRight作为普通用户随时查看用户凭据传递右边名称参数,你也是第一次传递给SetupAuthorizationForRight

// original code: https://developer.apple.com/library/mac/#technotes/tn2095/_index.html
//                https://developer.apple.com/library/mac/documentation/Security/Conceptual/authorization_concepts/03authtasks/authtasks.html#//apple_ref/doc/uid/TP30000995-CH206-BCIGEHDI


bool SetupAuthorizationForRight(const char* rightName)
// Called as the application starts up. Creates a connection
// to Authorization Services and then makes sure that our
// right is defined.
{
    OSStatus err;

    // Connect to Authorization Services.

    AuthorizationRef authorization = NULL;
    err = AuthorizationCreate(NULL, NULL, 0, &authorization);

    // Set up our rights.

    if (err == noErr) {
        // Check whether our right is already defined.
        err = AuthorizationRightGet(rightName, NULL);
        if (err == noErr) {

            // A right already exists, either set up in advance by
            // the system administrator or because this is the second
            // time we've run. Either way, there's nothing more for
            // us to do.

        } else if (err == errAuthorizationDenied) {

            // The right is not already defined. Let's create a
            // right definition based on the custom (not canned) rule defined
            // in the dictionary below.
            // The system administrator can modify this right as they
            // see fit.
            CFStringRef keys[2] = {CFSTR("class"), CFSTR("group")};
            CFStringRef values[2] = {CFSTR("user"), CFSTR("everyone")};
            // Allow access for every user - all of local and remote users are in the
            // 'everyone' group, so this is a safe rule
            CFDictionaryRef aDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 2,
                                                       &kCFCopyStringDictionaryKeyCallBacks,
                                                       &kCFTypeDictionaryValueCallBacks);

            err = AuthorizationRightSet(
                                        authorization,          // authRef
                                        rightName,              // rightName
                                        aDict,                  // rightDefinition
                                        CFSTR("Authenticate to log in via YourAppName."),          // descriptionKey
                                        NULL,                   // bundle, NULL indicates main
                                        NULL                    // localeTableName,
                                        ); // NULL indicates "Localizable.strings"

            if (aDict) {
                CFRelease(aDict);
            }

            if (err != noErr) {
                NSLog(@"Cannot set up authorization entry. Error: %d", err);
            }
        }
    } else {
        NSLog(@"Cannot open authorization database. Error: %d", err);
    }

    return (err == noErr);
}

bool AuthenticateForRight(const char* username, const char* password, const char* rightName)
{
    OSStatus status = noErr;

    if (rightName) {
        if ((status = SetupAuthorizationForRight(rightName)) != noErr)
            return false;
    }
    else
        rightName = "allow"; // Allow right rule always defined by default and only authenticated users has this right

    AuthorizationRef authRef = 0;

    AuthorizationItem   environment[2] = {{NULL, 0, NULL, 0}, {NULL, 0, NULL, 0}};
    int numItems = 0;
    if (username) {
        AuthorizationItem item = { kAuthorizationEnvironmentUsername, strlen(username), (char*)username, 0 };
        environment[numItems++] = item;
        if (password) {
            AuthorizationItem passItem = { kAuthorizationEnvironmentPassword, strlen(password), (char*)password, 0 };
            environment[numItems++] = passItem;
        }
    }

    AuthorizationItem right = {NULL, 0, NULL, 0};
    right.name = rightName;
    right.valueLength = 0;
    right.value = 0;
    AuthorizationRights rightSet = { 1, &right };
    AuthorizationRights environmentSet = { static_cast<unsigned int>(numItems), environment };

    status = AuthorizationCreate(NULL, &environmentSet, kAuthorizationFlagDefaults, &authRef);
    if (status != noErr) {
        NSLog(@"Cannot create authorization reference. Error: %d", status);
        return false;
    }

    AuthorizationFlags flags = kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;     // | kAuthorizationFlagInteractionAllowed; <- Just for debugging, will display the OS auth dialog if needed!!! 
    status = AuthorizationCopyRights(authRef, &rightSet, &environmentSet, flags, NULL );
    AuthorizationFree(authRef,kAuthorizationFlagDestroyRights);

    return (status == noErr);
}

答案 1 :(得分:0)

如果密码错误,

authorization services API将验证并再次提示。

答案 2 :(得分:0)

这是我的代码供您参考。

char *password = "password";
char *userName = "account";

AuthorizationRef authorization = NULL; 
AuthorizationItem items[2];
items[0].name = kAuthorizationEnvironmentPassword;
items[0].value = password;
items[0].valueLength = strlen(password);
items[0].flags = 0;
items[1].name = kAuthorizationEnvironmentUsername;
items[1].value = userName;
items[1].valueLength = strlen(userName);
items[1].flags = 0;

AuthorizationRights rights = {2, items};
AuthorizationEnvironment enviroment = {2, items};
// Creates a new authorization reference and provides an option to authorize or preauthorize rights.
AuthorizationCreate(NULL, &enviroment, kAuthorizationFlagDefaults, &authorization);
AuthorizationFlags flag = kAuthorizationFlagDefaults| kAuthorizationFlagExtendRights;

OSStatus status = AuthorizationCopyRights(authorization, &rights, &enviroment, flag, NULL);
if(status == errAuthorizationSuccess)
{
    NSLog(@"Pass");
}
else 
{
    NSLog(@"Fail");
}