使用 Authz API 检查访问

应用程序确定是否通过调用 AuthzAccessCheck 函数授予对安全对象的访问权限。

AuthzAccessCheck 函数将 AUTHZ_ACCESS_REQUESTSECURITY_DESCRIPTOR 结构作为参数。 AUTHZ_ACCESS_REQUEST结构指定请求的访问级别。 AuthzAccessCheck 函数针对指定客户端上下文的指定SECURITY_DESCRIPTOR评估请求的访问。 有关安全描述符如何控制对对象的访问的信息,请参阅 DACL 如何控制对对象的访问

与逻辑运算符一起使用时,属性变量必须采用表达式的形式;否则,它们将评估为未知。

回调函数

如果 任意访问控制列表 (待检查对象的 SECURITY_DESCRIPTOR DACL) 包含 (ACE) 的任何回调 访问控制项则 AuthzAccessCheck 针对 DACL 中包含的每个回调 ACE 调用 AuthzAccessCheckCallback 函数。 回调 ACE 是 ACE 类型包含单词“callback”的任何 ACE 结构。 AuthzAccessCheckCallback 函数是应用程序定义的函数,在通过调用 AuthzInitializeResourceManager 函数初始化资源管理器时,必须注册该函数。

回调函数允许应用程序定义要在运行时评估的业务逻辑。 调用 AuthzAccessCheckCallback 函数时,导致调用的回调 ACE 将传递到回调函数进行评估。 如果应用程序定义的逻辑的计算结果为 TRUE,则回调 ACE 将包含在访问检查中。 否则会忽略该设置。

缓存访问结果

访问检查的结果可以缓存,并在将来调用 AuthzCachedAccessCheck 函数时使用。 有关缓存访问检查的详细信息(包括示例),请参阅 缓存访问检查

示例

以下示例创建一个 允许READ_CONTROL 内置管理员访问 的SECURITY_DESCRIPTOR 。 它使用该安全描述符检查在初始化客户端上下文的示例中创建的客户端上下文所指定的客户端的访问

BOOL CheckAccess(AUTHZ_CLIENT_CONTEXT_HANDLE hClientContext)
{
    #define MY_MAX 4096


    PSECURITY_DESCRIPTOR    pSecurityDescriptor = NULL;
    ULONG                    cbSecurityDescriptorSize = 0;
    AUTHZ_ACCESS_REQUEST    Request;
    CHAR                    ReplyBuffer[MY_MAX];
    PAUTHZ_ACCESS_REPLY        pReply = (PAUTHZ_ACCESS_REPLY)ReplyBuffer;
    DWORD                    AuthzError =0;

    //Allocate memory for the access request structure.
    RtlZeroMemory(&Request, sizeof(AUTHZ_ACCESS_REQUEST));

    //Set up the access request structure.
    Request.DesiredAccess = READ_CONTROL;
    
    //Allocate memory for the access reply structure.
    RtlZeroMemory(ReplyBuffer, MY_MAX);

    //Set up the access reply structure.
    pReply->ResultListLength = 1;
    pReply->Error = (PDWORD) ((PCHAR) pReply + sizeof(AUTHZ_ACCESS_REPLY));
    pReply->GrantedAccessMask = (PACCESS_MASK) (pReply->Error + pReply->ResultListLength);
    pReply->SaclEvaluationResults = NULL;

    //Create security descriptor.
    if(!ConvertStringSecurityDescriptorToSecurityDescriptor(
        L"O:LAG:BAD:(A;;RC;;;BA)",
        SDDL_REVISION_1,
        &pSecurityDescriptor,
        NULL))
    {
        printf_s("ConvertStringSecurityDescriptorToSecurityDescriptor failed with %d\n", GetLastError()); 
        return FALSE;
    }

    //Call AuthzAccessCheck.
    if(!AuthzAccessCheck(
        0,
        hClientContext,
        &Request,
        NULL,
        pSecurityDescriptor,
        NULL,
        0,
        pReply,
        NULL))
    {
        printf_s("AuthzAccessCheck failed with %d\n", GetLastError());
        
    LocalFree(pSecurityDescriptor);
    
        return FALSE;
    }


    //Print results.
    if(*pReply->GrantedAccessMask & READ_CONTROL)
    {
        printf_s("Access granted.\n");
    }
    else
    {
        printf_s("Access denied.\n");
    }

  LocalFree(pSecurityDescriptor);
    return TRUE;

}

将 SID 添加到客户端上下文

缓存访问检查

初始化客户端上下文

查询客户端上下文