我正在开发一个C#实现的自定义凭据提供程序。
在交互式会话中,它可以正常工作没有任何问题。然而,当我尝试使用RDP(mstsc)连接该计算机时,在凭证序列化后会出现错误信息。错误信息如下:
"身份验证错误。提供给函数的令牌无效。" 在我的服务器上,GetSeralization方法如下所示;
public override int GetSerialization(out _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE pcpgsr, out _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcs, out string ppszOptionalStatusText, out _CREDENTIAL_PROVIDER_STATUS_ICON pcpsiOptionalStatusIcon)
{
pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_NO_CREDENTIAL_NOT_FINISHED;
pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();
ppszOptionalStatusText = "";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_NONE;
var otpResult = DialogResult.Yes;
// make OTP operation here
if (otpResult == DialogResult.Yes)
{
CredHelper.Instance.RetrieveNegotiateAuthPackage(out var authPackage);
var userNameField = credentialView.GetField(FieldTypeEnum.UsernameField);
var passwordField = credentialView.GetField(FieldTypeEnum.PasswordField);
var userNameSplitted = userNameField.Value.SplitSpecial('\\');
if (userNameSplitted.Count <= 1)
{
ppszOptionalStatusText = "Failed to pack credentials";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_ERROR;
return HResult.Fail;
}
pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_RETURN_CREDENTIAL_FINISHED;
pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();
NativeLogon.KerbInteractiveUnlockLogonInit(userNameSplitted.First(), userNameSplitted.Last(), passwordField.Value, (int)usageScenario, out KerbInteractiveUnlockLogon pkiul);
NativeLogon.KerbInteractiveUnlockLogonPack(ref pkiul, out IntPtr inCredBuffer, out int inCredSize);
ppszOptionalStatusText = string.Empty;
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_SUCCESS;
pcpcs.clsidCredentialProvider = Statics.CredentialProviderGuid;
pcpcs.rgbSerialization = inCredBuffer;
pcpcs.cbSerialization = (uint)inCredSize;
pcpcs.ulAuthenticationPackage = authPackage;
return HResult.Ok;
}
ppszOptionalStatusText = "Failed to pack credentials";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_ERROR;
return HResult.Fail;
}
以下是我的ICredentialProviderFilter
实现,但我认为它是错误的。
public int UpdateRemoteCredential(ref _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcsIn, out _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcsOut)
{
pcpcsOut = pcpcsIn;
return HResult.Ok;
}
我卡在这里了,无法继续前进。谢谢。