C# 如何使ActiveDirectoryMembershipProvider接受空密码?

C# 如何使ActiveDirectoryMembershipProvider接受空密码?,c#,.net,asp.net,authentication,activedirectorymembership,C#,.net,Asp.net,Authentication,Activedirectorymembership,我们正在开发一个web应用程序,它使用表单身份验证和ActiveDirectoryMembershipProvider根据Active Directory对用户进行身份验证。我们很快发现,提供程序不允许指定空/空密码,即使这在Active Directory中是完全合法的(前提是没有预防性的密码策略) 反射器提供: private void CheckPassword(string password, int maxSize, string paramName) { if (passwo

我们正在开发一个web应用程序,它使用表单身份验证和ActiveDirectoryMembershipProvider根据Active Directory对用户进行身份验证。我们很快发现,提供程序不允许指定空/空密码,即使这在Active Directory中是完全合法的(前提是没有预防性的密码策略)

反射器提供:

private void CheckPassword(string password, int maxSize, string paramName)
{
    if (password == null)
    {
        throw new ArgumentNullException(paramName);
    }
    if (password.Trim().Length < 1)
    {
        throw new ArgumentException(SR.GetString("Parameter_can_not_be_empty", new object[] { paramName }), paramName);
    }
    if ((maxSize > 0) && (password.Length > maxSize))
    {
        throw new ArgumentException(SR.GetString("Parameter_too_long", new object[] { paramName, maxSize.ToString(CultureInfo.InvariantCulture) }), paramName);
    }
}
private void CheckPassword(字符串密码、int-maxSize、字符串参数名)
{
如果(密码==null)
{
抛出新ArgumentNullException(paramName);
}
if(password.Trim().Length<1)
{
抛出新ArgumentException(SR.GetString(“参数不能为空”,新对象[]{paramName}),paramName);
}
如果((maxSize>0)和&(password.Length>maxSize))
{
抛出新的ArgumentException(SR.GetString(“参数_太长了”,新对象[]{paramName,maxSize.ToString(CultureInfo.InvariantCulture)}),paramName);
}
}

除了编写我们自己的自定义提供程序外,是否有任何方法可以使用.NET的魔力覆盖此功能?

您可能会考虑使用模拟,但我不知道您是否会遇到同样的问题。如果是授权用户,那么您可以使用模拟来尝试“模拟”计算机上的用户。我不知道这是否有帮助,但前几周我做了类似的事情。如果有任何帮助,请在下面输入代码:)


我不相信您可以在不创建派生类和覆盖每个调用私有CheckPassword方法的方法的情况下更改这种行为。我不推荐这个选项,但是,我建议您检查您的设计,并质疑在应用程序中允许空白密码是否合适。虽然它们在AD中有效,但在实践中不允许这样做,这确实会影响windows网络中的其他事情,例如,我认为网络文件共享的默认设置不允许任何使用空密码的用户连接到共享。

您可以使用空/空密码连接到文件共享和映射网络驱动器等,除了ActiveDirectoryMembershipProvider之外,它受到了全面的支持。您是对的,如果不创建子类,就无法专门重写此行为。
using System;  
using System.Runtime.InteropServices;  

public partial class Test_Index : System.Web.UI.Page {  
protected void Page_Load(object sender, EventArgs e)
{        
    IntPtr ptr = IntPtr.Zero;
    if (LogonUser("USERNAME", "", "LEAVE-THIS-BLANK", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref ptr))
    {
        using (System.Security.Principal.WindowsImpersonationContext context = new System.Security.Principal.WindowsIdentity(ptr).Impersonate())
        {
            try
            {
                // Do do something
            }
            catch (UnauthorizedAccessException ex)
            {
                // failed to do something
            }

            // un-impersonate user out
            context.Undo();
        }
    }
    else
    {
        Response.Write("login fail");
    }
}

#region imports

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);

#endregion

#region logon consts

// logon types 
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

// logon providers 
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
#endregion  }