我想实现通过 SmartCard 解锁 Windows 会话的自定义 WindowsCredentialProvider。使用 //username & password 可以正常工作,但 SmartCard 有问题。我使用此示例https://github.com/phaetto/windows-credentials-provider并根据此主题进行更改https://docs.microsoft.com/en-gb/windows/win32/api/wincred/nf -wincred-credpackauthenticationbuffera并调用 CredMarshalCredential 如下:
NativeMethods.CERT_CREDENTIAL_INFO certInfo = new NativeMethods.CERT_CREDENTIAL_INFO();
certInfo.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.CERT_CREDENTIAL_INFO));
X509Certificate2 certCredential = new X509Certificate2();
var userMyStore = new X509Store();
userMyStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certsReturned = userMyStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
userMyStore.Close();
if (certsReturned.Count == 0)
{
Console.WriteLine("Could not find the cert you want, aborting");
return null;
}
certCredential = certsReturned[0];
certInfo.rgbHashOfCert = certCredential.GetCertHash();
int size = Marshal.SizeOf(certInfo);
IntPtr pCertInfo = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(certInfo, pCertInfo, false);
IntPtr marshaledCredential = IntPtr.Zero;
bool result = NativeMethods.CredMarshalCredential(NativeMethods.CRED_MARSHAL_TYPE.CertCredentia, pCertInfo, out marshaledCredential);
var user = "";
if (result)
{
user = Marshal.PtrToStringUni(marshaledCredential);
var psCreds = new PSCredential(user, new SecureString());
}
然后将 Username 和 SmartCard PIN 传递给 CredPackAuthenticationBuffer 函数并返回 True,但无法解锁屏幕。我还记录了凭证方法调用,如下所示:
TestWindowsCredentialProvider::Advise
TestWindowsCredentialProvider::GetCredentialCount
TestWindowsCredentialProvider::GetCredentialAt
TestWindowsCredentialProvider::GetFieldDescriptorCount
TestWindowsCredentialProvider::GetFieldDescriptorAt
TestWindowsCredentialProvider::GetFieldDescriptorAt
TestWindowsCredentialProviderTile::GetStringValue
TestWindowsCredentialProviderTile::GetFieldState
TestWindowsCredentialProviderTile::GetFieldState
TestWindowsCredentialProviderTile::GetSubmitButtonValue
TestWindowsCredentialProviderTile::Advise
TestWindowsCredentialProviderTile::SetSelected
TestWindowsCredentialProviderTile::SetSelected
TestWindowsCredentialProviderTile::GetSerialization
TestWindowsCredentialProviderTile::SetDeselected
TestWindowsCredentialProviderTile::UnAdvise
TestWindowsCredentialProvider::UnAdvise
更新:当我使用域\用户名和密码时,日志是相同的,除了在 SetDeselected 之后调用 ReportResult
TestWindowsCredentialProviderTile::ReportResult