Удаленный вход в систему провайдера учетных данных Windows

Я пытаюсь прочитать учетные данные со смарт-карты на одной рабочей станции (локальной), а затем отправить ее на другую рабочую станцию ​​(удаленную) и использовать ее для входа на эту рабочую станцию ​​из провайдера учетных данных.

Я искал и изучал уже несколько недель, но не нашел никого, кто бы показывал или рассказывал, как это сделать.

Я нашел несколько ссылок на отличную работу по адресу https://www.idrix.fr/Root/Samples/LsaSmartCardLogon2.cpp, который является рабочим кодом для поставщика учетных данных смарт-карт, но, к сожалению, требует, чтобы поставщик учетных данных имел прямой доступ к смарт-карта с учетными данными на нем.

Фактический код, с которым я работаю, кажется, слишком длинным для включения в пост, поэтому я решил попробовать задать вопрос с использованием кода sudo. На локальной рабочей станции:

MySendCredentialsFromSmartCard(){
    CryptAcquireContext(hProv, containerName, cardName, PROV_RSA_FULL, CRYPT_SILENT) 
    CryptGetUserKey(*hProv, AT_KEYEXCHANGE, &hCryptKey); 
    CryptGetKeyParam(hCryptKey, KP_CERTIFICATE, encodedCert, &size, 0); 
    MySendCertToRemote(encodedCert,size); 
} 

На удаленной рабочей станции, работающей в провайдере пользовательских учетных данных:

HRESULT CSampleCredential::GetSerialization( 
    _Out_ CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *pcpgsr, 
    _Out_ CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcs, 
    _Outptr_result_maybenull_ PWSTR *ppwszOptionalStatusText, 
    _Out_ CREDENTIAL_PROVIDER_STATUS_ICON *pcpsiOptionalStatusIcon){ 

    MyReadCertFromRemote(&cert,&size); 
    CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0); 
    CryptCreateHash(hCryptProv, CALG_SHA1, NULL, 0, &hHash); 
    CryptHashData(hHash, (BYTE *)cert, (DWORD)size, 0); 

    CERT_CREDENTIAL_INFO certInfo; 

    CryptGetHashParam(hHash, HP_HASHVAL, certInfo.rgbHashOfCert, &dwHashLen, 0); 
    CredMarshalCredential(CertCredential, &certInfo, marshalledCred); 
/****************************for debug only*****************************/ 
    LogonUser((*marshalledCred, NULL, NULL, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &userHandle); 
//this reuturns 1 (success) 
/**************************************************************************/ 
    KERB_INTERACTIVE_UNLOCK_LOGON kiul; 
    CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus 
    KerbInteractiveUnlockLogonInit(L"", (PWSTR)marshaledCred, L"", cpus, &kiul);//(note:I've tried this with the third param set to the card's pin) 
    KerbInteractiveUnlockLogonPack(kiul, &pcpcs->rgbSerialization, &pcpcs->cbSerialization); 
    RetrieveNegotiateAuthPackage(&ulAuthPackage); 
    pcpcs->ulAuthenticationPackage = ulAuthPackage; 
    pcpcs->clsidCredentialProvider = CLSID_OfProvider; 
    *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED; 
} 

LogonUI.exe отображает "Указанный сеанс входа в систему не существует. Возможно, он уже был прерван". Это похоже на код ошибки Windows 1312. Кажется, что большинство разработчиков, борющихся с этим кодом ошибки, испытывают трудности при настройке IIS с сертификатом SSL. Я не нашел ссылки на эту ошибку в отношении поставщика учетных данных. Кажется, что различные потоки указывают, что LogonUser - просто оболочка вокруг LSALogonUser, и возвращенные значения из ICredentialProviderCredential::GetSerialization будут переданы LSALogonUser. Тот факт, что мой звонок в LogonUser с маршализованными учетными данными успешен, может показаться, что я на правильном пути, но я не смог ни это проверить, ни выяснить, что мне не хватает. Я хотел бы попытаться избежать решений, которые требуют хранения учетных данных на удаленной рабочей станции, поскольку это, как правило, учетные данные администратора домена. Есть идеи кто-нибудь? Любой совет, как поступить?

Спасибо

1 ответ

Я полагаю, что вы можете сделать это, используя механизм связи, при котором вы отправляете свои данные с одной рабочей станции на другую, а на удаленной вы сериализуете свои данные в SetSerialization() вместо GetSerialization(), подготавливая все поля и обрабатывая вход в систему.

С моей точки зрения, класс Provider (наследуемый ICredentialProvider) должен каким-то образом ждать эти учетные данные и передавать их в SetSerialization.

Другие вопросы по тегам