Как заставить ActiveDirectoryMembershipProvider принимать пустой пароль?

Мы разрабатываем веб-приложение, которое использует проверку подлинности с помощью форм и 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);
    }
}

Если не считать написания нашего собственного провайдера, есть ли способ переопределить эту функциональность, используя магию .NET?


person fletcher    schedule 19.07.2010    source источник


Ответы (2)


Я не верю, что вы могли бы изменить это поведение без создания производного класса и переопределения каждого метода, который вызывает частный метод CheckPassword. Однако я бы не рекомендовал этот вариант, я бы рекомендовал вам просмотреть свой дизайн и задаться вопросом, уместно ли разрешать пустые пароли в вашем приложении. Хотя они действительны в AD, на практике это необычно, и это влияет на другие вещи в сети Windows, например. я думаю, что настройки по умолчанию для сетевых файловых ресурсов запрещают любому пользователю с пустым паролем подключаться к общему ресурсу.

person Ben Robinson    schedule 19.07.2010
comment
Вы можете подключаться к общим файловым ресурсам и подключать сетевые диски и т. д. с пустым/пустым паролем, он поддерживается повсеместно, кроме ActiveDirectoryMembershipProvider. Вы правы, невозможно переопределить это поведение без создания подкласса. - person fletcher; 28.07.2010

Возможно, вы могли бы взглянуть на использование олицетворения, но я не знаю, будет ли у вас такая же проблема. Если это авторизация пользователя, вы можете использовать олицетворение, чтобы попытаться «выдать себя за» пользователя на машине. Я не знаю, поможет ли это, но я делал что-то подобное на прошлой неделе. Поместите код ниже, если это поможет .. :)

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  }
person dan richardson    schedule 19.07.2010