LogonUser - 告知用户登录失败的原因

时间:2016-05-18 21:20:04

标签: c# authentication active-directory

目前我们有以下代码:

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern bool LogonUser(string username, string domain, string password, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
    bool isLoggedIn = LogonUser(...);
    if(isLoggedIn){
       // Some Code...
    } else {
       // Need to: 
       // If user entered incorrect password
       // If the user is locked/banned out of the system
    }

我们的活动目录配置在x登录尝试失败后锁定用户。有没有办法检查登录失败是因为用户输入的密码不正确,还是因为尝试次数太多而被锁定?另外,有没有办法要求AD允许的尝试次数?我们的管理员似乎不断更改这些数字,因此我不想在应用中对其进行硬编码

2 个答案:

答案 0 :(得分:1)

根据advapi32.dll的文档,您可以通过调用GetLastError

获取有关登录失败原因的详细信息

https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx

ofc你必须为该方法添加一个extern。此外,我建议查看评论,因为有人发布了代码以从错误中提取文本,这可能是您想要向用户显示的内容。

此外,您可以使用FormatMessage方法产生更好的错误。它与上面的文档相关联,但这里是它的直接链接; https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx

答案 1 :(得分:1)

返回值

  

如果函数成功,则函数返回非零值。
  如果函数失败,则返回零。要获取扩展错误信息,请调用GetLastError。

根据文档,您应检查上一个错误。但是,不要在C#中调用GetLastError(),你应该采用托管方式:

else
{
    // Need to: 
    // If user entered incorrect password
    // If the user is locked/banned out of the system

    var errorCode = Marshal.GetLastWin32Error();
    var exception = new Win32Exception(errorCode);

    // exception.Message should contain the information you need.
    // alternatively, you can switch on errorCode to provide your custom message
}

作为参考,您可以在此处查找错误代码:System Error Codes

  

备注
  GetLastWin32Error从Kernel32.DLL公开Win32 GetLastError函数。存在此方法是因为直接平台调用GetLastError来获取此信息是不安全的。如果要访问此错误代码,则必须调用GetLastWin32Error,而不是为GetLastError编写自己的平台调用定义并调用它。公共语言运行库可以对API进行内部调用,覆盖操作系统维护的GetLastError。

来源:Marshal.GetLastWin32Error