凭据提供程序接受旧的Windows Live帐户密码

问题描述

对于我们的一位客户,我们创建了一个自定义的凭证提供程序,该提供程序接收解密密钥和加密文件名,该文件名包含用户名和密码。此机制非常适合本地用户帐户。在需要时对用户进行身份验证,并且在用户更改密码后即不再接受旧密码。

但是,对于Windows Live帐户,用户有时可以在联机更改密码(accounts.microsoft.com)之后甚至使用新创建的密码登录Windows后,也可以使用其旧密码登录。奇怪的是,用户无法通过键入其旧密码来登录。仅在使用凭据提供程序时有效。

为了使它更加混乱,有时它会按预期运行,并且行为因计算机而异。

我的直觉告诉我,用于验证用户身份的代码有问题,但是我无法弄清楚出了什么问题。我们已经尝试设置OldPasswordAllowedPeriod注册表值,但这似乎不起作用。

我们使用以下GetSerialization()实现来填充身份验证缓冲区:

public int GetSerialization(...)
        {
            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;

            try
            {
                var inCredSize = 0;
                var inCredBuffer = Marshal.AllocCoTaskMem(0);
                
                if (string.IsNullOrEmpty(_username) || _password == null || _password.Length == 0)
                {
                    return SetAuthenticationError(out pcpgsr,out pcpsiOptionalStatusIcon,out ppszOptionalStatusText,"This NFC card has not been registered on this screen.");
                }

                if (!PInvoke.CredPackAuthenticationBuffer(0,_username,securestringToString(_password),inCredBuffer,ref inCredSize))
                {
                    Marshal.FreeCoTaskMem(inCredBuffer);
                    inCredBuffer = Marshal.AllocCoTaskMem(inCredSize);

                    if (PInvoke.CredPackAuthenticationBuffer(0,ref inCredSize))
                    {
                        pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_RETURN_CREDENTIAL_FINISHED;
                        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 HResult.S_OK;
                    }

                    _logger.LogError($"Failed to pack credentials for: {_username}.");
                    return SetAuthenticationError(out pcpgsr,"Failed to pack credentials.");
                }

                _logger.LogWarning("GetSerialization unexpectedly preliminary succesfully buffered credentials");
                return SetAuthenticationError(out pcpgsr,"Something unexpected went wrong!");
            }
            catch (Exception ex)
            {
                // In case of any error,do not bring down winlogon
                _logger.LogError(ex);
                return SetAuthenticationError(out pcpgsr,"Something unexpected went wrong!");
            }
            finally
            {
                _shouldAutoLogin = false; // Block auto-login from going full-retard
            }
}

有人可以指出正确的方向来解决这个问题吗?或者,有人对使用我们的自定义凭据提供程序验证用户身份时的错误想法有什么想法?

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)