Квалификация доступа с помощью бизнес-логики на C++
Используйте сценарии бизнес-правил для предоставления логики времени выполнения для проверки доступа. Дополнительные сведения о бизнес-правилах см. в разделе Бизнес-правила.
Чтобы назначить бизнес-правило задаче, сначала задайте свойство BizRuleLanguage объекта IAzTask , представляющего задачу. Скрипт должен быть в выпуске Visual Basic Scripting Edition или JScript. После указания языка скрипта задайте свойство BizRule объекта IAzTask со строковым представлением скрипта.
При проверке доступа для операции, содержащейся в задаче с связанным бизнес-правилом, приложение должно создать два массива одинакового размера, которые будут переданы в качестве параметров varParameterNames и varParameterValues метода IAzClientContext::AccessCheck . Сведения о создании контекста клиента см. в разделе Установка контекста клиента с помощью диспетчера авторизации в C++.
Метод IAzClientContext::AccessCheck создает объект AzBizRuleContext , который передается в скрипт бизнес-правила. Затем скрипт задает свойство BusinessRuleResult объекта AzBizRuleContext . Значение TRUE указывает, что доступ предоставлен, а значение FALSE указывает, что доступ запрещен.
Скрипт бизнес-правил не может быть назначен объекту IAzTask , который содержится в делегированном объекте IAzScope .
В следующем примере показано, как использовать скрипт бизнес-правила для проверка доступа клиента к операции. В примере предполагается, что в корневом каталоге диска C имеется хранилище политик XML с именем MyStore.xml, что это хранилище содержит приложение с именем Expense, задачу с именем Submit Expense и операцию с именем UseFormControl, а переменная hToken содержит допустимый маркер клиента.
#include <windows.h>
#include <stdio.h>
#include <azroles.h>
void CheckAccess(ULONGLONG hToken)
// Void CheckAccess().
{
IAzAuthorizationStore* pStore = NULL;
IAzApplication* pApp = NULL;
IAzClientContext* pClientContext = NULL;
IAzOperation* pOperation = NULL;
IAzTask* pTask = NULL;
BSTR storeName = NULL;
BSTR appName = NULL;
BSTR operationName = NULL;
BSTR objectName = NULL;
BSTR taskName = NULL;
BSTR bizRule = NULL;
BSTR bizRuleLanguage = NULL;
LONG operationID;
HRESULT hr;
VARIANT varOperationIdArray;
VARIANT varOperationId;
VARIANT varResultsArray;
VARIANT varResult;
VARIANT varParamName;
VARIANT varParamValue;
VARIANT nameString;
VARIANT expenseAmount;
void MyHandleError(char *s);
VARIANT myVar;
VariantInit(&myVar);
// Initialize COM.
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not initialize COM.");
// Create the AzAuthorizationStore object.
hr = CoCreateInstance(
/*"b2bcff59-a757-4b0b-a1bc-ea69981da69e"*/
__uuidof(AzAuthorizationStore),
NULL,
CLSCTX_ALL,
/*"edbd9ca9-9b82-4f6a-9e8b-98301e450f14"*/
__uuidof(IAzAuthorizationStore),
(void**)&pStore);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not create AzAuthorizationStore object.");
// Allocate a string for the policy store.
if(!(storeName = SysAllocString(L"msxml://c:\\MyStore.xml")))
MyHandleError("Could not allocate string.");
// Initialize the store.
hr = pStore->Initialize(0, storeName, myVar);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not initialize store.");
// Create an application object.
if (!(appName = SysAllocString(L"Expense")))
MyHandleError("Could not allocate application name string.");
hr = pStore->OpenApplication(appName, myVar, &pApp);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not open application.");
// Create a client context from a token handle.
hr = pApp->InitializeClientContextFromToken(hToken, myVar,
&pClientContext);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not create client context.");
// Create a business rule for the Submit Expense task.
// Open the Submit Expense task.
if(!(taskName = SysAllocString(L"Submit Expense")))
MyHandleError("Could not allocate task name string.");
hr = pApp->OpenTask(taskName, myVar, &pTask);
// Assign a business rule to the task.
// Set the business rule language to VBScript.
if(!(bizRuleLanguage = SysAllocString(L"VBScript")))
MyHandleError("Could not allocate business rule language string.");
hr = pTask->put_BizRuleLanguage(bizRuleLanguage);
if(!(SUCCEEDED(hr)))
MyHandleError("Could not allocate business rule language string.");
// Create a BSTR with the business rule code.
if(!(bizRule = SysAllocString(
L"Dim Amount \n"
L"AzBizRuleContext.BusinessRuleResult = FALSE \n"
L"Amount = AzBizRuleContext.GetParameter(\"ExpAmount\") \n"
L"if Amount < 500 then AzBizRuleContext.BusinessRuleResult = TRUE"
)))
MyHandleError("Could not allocate business rule string.");
hr = pTask->put_BizRule(bizRule);
if(!(SUCCEEDED(hr)))
MyHandleError("Could not assign business rule.");
// Save the new task data to the store.
hr = pTask->Submit(0, myVar);
if(!(SUCCEEDED(hr)))
MyHandleError("Could not save task data.");
// Set up parameters for access check.
// Set up the object name.
if (!(operationName = SysAllocString(L"UseFormControl")))
MyHandleError("Could not allocate operation name string.");
// Get the ID of the operation to check.
hr = pApp->OpenOperation(operationName, myVar, &pOperation);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not open operation.");
hr = pOperation->get_OperationID(&operationID);
if(!(SUCCEEDED(hr)))
MyHandleError("Could not get operation ID.");
// Create a SAFEARRAY for the operation ID.
varOperationIdArray.parray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
// Create an array of indexes.
LONG* index = new LONG[1];
index[0] = 0;
// Populate a SAFEARRAY with the operation ID.
varOperationId.vt = VT_I4;
varOperationId.lVal = operationID;
hr = SafeArrayPutElement(varOperationIdArray.parray, index,
&varOperationId);
if(!(SUCCEEDED(hr)))
MyHandleError("Could not put operation ID in array.");
// Set SAFEARRAY type.
varOperationIdArray.vt = VT_ARRAY | VT_VARIANT;
// Create business rule parameters.
// Create array of business rule parameter names.
varParamName.parray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
varParamName.vt = VT_ARRAY | VT_VARIANT;
nameString.vt = VT_BSTR;
nameString.bstrVal = SysAllocString(L"ExpAmount");
SafeArrayPutElement(varParamName.parray, index, &nameString);
// Create array of business rule parameter values.
varParamValue.parray = SafeArrayCreateVector(VT_VARIANT, 0, 1);
varParamValue.vt = VT_ARRAY | VT_VARIANT;
expenseAmount.vt = VT_I4;
expenseAmount.lVal = 100; // access denied if 500 or more
SafeArrayPutElement(varParamValue.parray, index, &expenseAmount);
if(!(objectName = SysAllocString(L"UseFormControl")))//used for audit
MyHandleError("Could not allocate object name string.");
// Check access.
hr = pClientContext->AccessCheck(
objectName,
myVar, // use default application scope
varOperationIdArray,
varParamName,
varParamValue,
myVar,
myVar,
myVar,
&varResultsArray);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not complete access check.");
hr = SafeArrayGetElement(varResultsArray.parray, index, &varResult);
if (!(SUCCEEDED(hr)))
MyHandleError("Could not get result from array.");
if (varResult.lVal == 0)
printf("Access granted.\n");
else
printf("Access denied.\n");
// Clean up resources.
pStore->Release();
pApp->Release();
pOperation->Release();
pClientContext->Release();
pTask->Release();
SysFreeString(storeName);
SysFreeString(appName);
SysFreeString(operationName);
SysFreeString(objectName);
SysFreeString(taskName);
SysFreeString(bizRule);
SysFreeString(bizRuleLanguage);
VariantClear(&myVar);
VariantClear(&varOperationIdArray);
VariantClear(&varOperationId);
VariantClear(&varResultsArray);
VariantClear(&varResult);
VariantClear(&varParamName);
VariantClear(&varParamValue);
VariantClear(&nameString);
VariantClear(&expenseAmount);
CoUninitialize();
}
void MyHandleError(char *s)
{
printf("An error occurred in running the program.\n");
printf("%s\n",s);
printf("Error number %x\n.",GetLastError());
printf("Program terminating.\n");
exit(1);
}