IIS客户端证书映射验证

时间:2013-12-13 05:03:05

标签: c++ windows iis windows-server-2008

我正在尝试以编程方式将onetoone客户端证书身份验证添加到applicationhost.config文件中。

在引用这两个文档(thread1,thread2)后,我确信可以用不同的语言实现它。出于某种原因,我必须用C ++开发它。在thread1中翻译代码示例时,

以下是代码段FYI。

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ahadmin.h>
#include <crtdbg.h>
#include <string>

using namespace std;

void PrintPropertiesOfElement(IAppHostElement *pElement)
{
HRESULT hr = S_OK;

IAppHostPropertyCollection *pProperties = NULL;
IAppHostProperty *pProperty = NULL;

hr = pElement->get_Properties(&pProperties);

DWORD properties_count = 0;
hr = pProperties->get_Count(&properties_count);

VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<properties_count; ++i)
{
    vtIndex.intVal = i;
    hr = pProperties->get_Item(vtIndex, &pProperty);

    BSTR strName;
    BSTR strValue;
    hr = pProperty->get_Name(&strName);
    hr = pProperty->get_StringValue(&strValue);
    _tprintf(_T("name : %s,  value: %s\n"), strName, strValue);
}
}


void PrintElementsOfCollection(IAppHostChildElementCollection *pCollection)
{
HRESULT hr = S_OK;

IAppHostElement *pElement = NULL;

DWORD elements_count = 0;
hr = pCollection->get_Count(&elements_count);

VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<elements_count; ++i)
{
    vtIndex.intVal = i;
    hr = pCollection->get_Item(vtIndex, &pElement);

    BSTR strName;
    hr = pElement->get_Name(&strName);
    _tprintf(_T("element : %s\n"), strName);
}
}

void PrintElementsOfCollection(IAppHostElementCollection *pCollection)
{
HRESULT hr = S_OK;

IAppHostElement *pElement = NULL;

DWORD elements_count = 0;
hr = pCollection->get_Count(&elements_count);

VARIANT vtIndex;
vtIndex.vt = VT_INT;
for(DWORD i=0; i<elements_count; ++i)
{
    vtIndex.intVal = i;
    hr = pCollection->get_Item(vtIndex, &pElement);

    BSTR strName;
    hr = pElement->get_Name(&strName);
    _tprintf(_T("element : %s\n"), strName);

    //PrintPropertiesOfElement(pElement);
}
}

struct UserCertification
{
VARIANT username;
VARIANT password;
VARIANT certification;

public:
    UserCertification(wstring name, wstring pwd, wstring cert)
    {
    username.vt = VT_BSTR;
    username.bstrVal = SysAllocString(name.c_str());

    password.vt = VT_BSTR;
    password.bstrVal = SysAllocString(pwd.c_str());

    certification.vt = VT_BSTR;
    certification.bstrVal = SysAllocString(cert.c_str());
}
};

HRESULT SetHostElementProperty(IAppHostElement *pElement, UserCertification *pUserCert)
{
HRESULT hr = S_OK;

IAppHostProperty *pProperty = NULL;

BSTR name = SysAllocString(L"userName");
BSTR password = SysAllocString(L"password");
BSTR certification = SysAllocString(L"certificate");

//name
hr = pElement->GetPropertyByName(name, &pProperty);
pProperty->put_Value(pUserCert->username);

//password
hr = pElement->GetPropertyByName(password, &pProperty);
pProperty->put_Value(pUserCert->password);

//certification
hr = pElement->GetPropertyByName(certification, &pProperty);
pProperty->put_Value(pUserCert->certification);

return hr;
}

UserCertification* GenerateUserCertification()
{
wstring username = L"jinqiu.tao@emacle.com";
wstring password = L"123456";
wstring certificate = L"xxxxxxxx";

return new UserCertification(username, password, certificate);
}

int _tmain(int argc, _TCHAR* argv[])
{
HRESULT                               hr          = S_OK;

IAppHostWritableAdminManager        * pWMgr       = NULL;
IAppHostConfigManager               * pCfgMgr     = NULL;
IAppHostConfigFile                  * pCfgFile    = NULL;
IAppHostConfigLocationCollection * pLocations  = NULL;

IAppHostElement *pAdminSection = NULL;
IAppHostElementCollection *pElementCollection = NULL;
IAppHostChildElementCollection *pChildElements = NULL;
IAppHostElement *pElement = NULL;
IAppHostElement *pNewElement = NULL;

BSTR bstrConfigCommitPath = SysAllocString(L"MACHINE/WEBROOT/APPHOST/Default Web Site");
BSTR bstrSectionName = SysAllocString(L"system.webServer/security/authentication/iisClientCertificateMappingAuthentication");
BSTR bstrOneToOne = SysAllocString(L"oneToOneMappings");
BSTR bstrElementName = SysAllocString(L"add");

// Initialize
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );

// Create
hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), NULL,
    CLSCTX_INPROC_SERVER,
    __uuidof( IAppHostWritableAdminManager ), (void**) &pWMgr );

pWMgr -> put_CommitPath ( bstrConfigCommitPath );

hr = pWMgr->GetAdminSection(bstrSectionName, bstrConfigCommitPath, &pAdminSection);

hr = pAdminSection->get_ChildElements(&pChildElements);

PrintElementsOfCollection(pChildElements);

hr = pAdminSection->GetElementByName(bstrOneToOne, &pElement);

hr = pElement->get_Collection(&pElementCollection);

//PrintElementsOfCollection(pElementCollection);

hr = pElementCollection->CreateNewElement(bstrElementName, &pNewElement);

//PrintPropertiesOfElement(pNewElement);

hr = SetHostElementProperty(pNewElement, GenerateUserCertification());

    //got and error saying that another process is accesssing the data
hr = pElementCollection->AddElement(pNewElement);  //got an error code 0x80070021 here |||||||||||||||||

PrintElementsOfCollection(pElementCollection);

// Commit the changes to the configuration system
pWMgr->CommitChanges ( );
return 0;
}

如您所见,我可以创建一个新元素,但无法将其添加到元素集合中。

我想要做的只是在onetoonemappings部分添加一条记录。

<location path="Default Web Site">
        <system.webServer>
            <security>
                <access sslFlags="None" />
                <authentication>
                    <anonymousAuthentication enabled="true" />
                    <iisClientCertificateMappingAuthentication enabled="true" oneToOneCertificateMappingsEnabled="true">
                        <oneToOneMappings>
                            <add userName="yonggui.yu@emacle.com" password="[enc:AesProvider:4QEVwn3c530VH5sdwCl+Sm8G2eJesNEs4SaL6U5LrXg=:enc]" certificate="MIIFOjCCBCKgAwIBAgIKOAV" />
                            <add userName="yuyonggui@tbp.com" password="[enc:AesProvider:iBqmPwvbefiuiUZ03AyPD/0AxzD0HIb4SlJXKQGr9Ug=:enc]" certificate="MIIEjzCCA3egAwIBAgIKGgSFpwAAAA" />
                            <add userName="yonggui.yu@emacle.com" password="[enc:AesProvider:DogNZMKGrLa9ih2IO9PiMNUz9Ucggu9icKD7o8+U8dQ=:enc]" certificate="MIIFZzCCBE+gAwIBAgIHGAOD3e2==" />
                        </oneToOneMappings>
                    </iisClientCertificateMappingAuthentication>
                </authentication>
        </security>
    </system.webServer>

我希望我已经说清楚了。如果您需要任何其他信息,请随时通知我。

期待您的帮助。

最诚挚的问候,

约旦

0 个答案:

没有答案