I am trying to programmatically add onetoone client certificate authentication to the applicationhost.config file.
After referring to these two documents(thread1, thread2), I am sure that it is possible to implement it with different languages. And for some kind of reason I have to develop it with C++. While translating the code sample in thread1,
Below is the code snippet 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;
}
As you see, I can create a new element, but not able to add it to the element collection.
What I want to do is just add a record to the onetoonemappings part.
<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>
I hope that I have made it clear enough. If you guys need any kind of additional information, please do not hesitate to inform me.
Looking forward for your help.
Best Regards,
Jordan
User contributions licensed under CC BY-SA 3.0