C# 在凭据提供程序中提交登录

C# 在凭据提供程序中提交登录,c#,credential-providers,C#,Credential Providers,我读了这篇文章来开发我的自定义凭证提供程序 现在我想测试中文章附带的代码 我跑 安装.reg文件 通过更改场景运行代码并在登录屏幕中显示GUI private static bool IsSupportedScenario(_CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus) { switch (cpus) { case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CP

我读了这篇文章来开发我的自定义凭证提供程序

现在我想测试中文章附带的代码

  • 我跑 安装.reg文件

  • 通过更改场景运行代码并在登录屏幕中显示GUI

     private static bool IsSupportedScenario(_CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus)
    
         {
    
           switch (cpus)
            {
    
             case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_CREDUI:
                return true;
    
            case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_UNLOCK_WORKSTATION:
                return true;
    
            case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_LOGON:
                return true;
            case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_CHANGE_PASSWORD:
            case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_PLAP:
            case _CREDENTIAL_PROVIDER_USAGE_SCENARIO.CPUS_INVALID:
            default:
                return false;
        }
    }
    

问题是,如果正确,我如何提交插入的用户名/密码并成功登录?

您是否正在搜索此示例:?

我使用此示例。如问题中所述更改使用场景,并在此函数中输入用户名/密码

public int GetSerialization(out _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE pcpgsr,
            out _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcs, out string ppszOptionalStatusText,
            out _CREDENTIAL_PROVIDER_STATUS_ICON pcpsiOptionalStatusIcon)
        {
            Log.LogMethodCall();

            try
            {
                pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_RETURN_CREDENTIAL_FINISHED;
                pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();

                var username = "Domain\\username";
                var password = "password";
                var inCredSize = 0;
                var inCredBuffer = Marshal.AllocCoTaskMem(0);

                if (!PInvoke.CredPackAuthenticationBuffer(0, username, password, inCredBuffer, ref inCredSize))
                {
                    Marshal.FreeCoTaskMem(inCredBuffer);
                    inCredBuffer = Marshal.AllocCoTaskMem(inCredSize);

                    if (PInvoke.CredPackAuthenticationBuffer(0, username, password, inCredBuffer, ref inCredSize))
                    {
                        ppszOptionalStatusText = string.Empty;
                        pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_SUCCESS;

                        pcpcs.clsidCredentialProvider = Guid.Parse(Constants.CredentialProviderUID);
                        pcpcs.rgbSerialization = inCredBuffer;
                        pcpcs.cbSerialization = (uint)inCredSize;

                        RetrieveNegotiateAuthPackage(out var authPackage);
                        pcpcs.ulAuthenticationPackage = authPackage;

                        return HResultValues.S_OK;
                    }

                    ppszOptionalStatusText = "Failed to pack credentials";
                    pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_ERROR;
                    return HResultValues.E_FAIL;
                }
            }
            catch (Exception)
            {
                // In case of any error, do not bring down winlogon
            }
            finally
            {
                shouldAutoLogin = false; // Block auto-login from being stupid
            }

            pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_NO_CREDENTIAL_NOT_FINISHED;
            pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();
            ppszOptionalStatusText = string.Empty;
            pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_NONE;
            return HResultValues.E_NOTIMPL;
        }

最后,我可以测试.net自定义凭据提供程序。

这也让我挂断了一段时间。但这只是我对凭证提供者如何工作以及如何实现其接口的误解

实际上,您并不是自己“提交”凭证。您只需通过填充_-CREDENTIAL\u-PROVIDER\u-CREDENTIAL\u-SERIALIZATION将它们序列化,如上面接受的答案所示,Windows负责将它们实际提交到Winlogon.exe

然后可以在ReportResult()方法中检查提交文件的结果