Подтвердить что ты не робот

Как поддерживать аутентификацию NTLM с возвратом в ASP.NET MVC?

Как я могу реализовать следующее в приложении ASP.NET MVC:

  • пользователь открывает веб-сайт интрасети
  • пользователь молча аутентифицируется, если возможно
  • если проверка подлинности NTLM не сработала, покажите регистрационную форму пользователю
  • пользователь указывает пароль для входа и выбирает домен из списка предопределенных доменов
  • пользователь аутентифицируется в коде с использованием AD

Я знаю, как реализовать 4 и 5, но не могу найти информацию о том, как объединить NTLM и формы. Так что диалог NTLM для внутреннего входа/пароля никогда не отображается - прозрачная аутентификация или приятная страница входа в систему.

Как работать? Следует ли запрашивать логин и пароль? Могут ли ее текущие учетные данные (имя домена) использоваться без запроса ввода логина и пароля?

ОБНОВЛЕНИЕ для них, исследуя ту же проблему:

Когда я спрашивал об этом, я не совсем понял, как работает аутентификация NTLM внутри. Важно понять, что если браузер пользователя не поддерживает NTLM должным образом или если поддержка NTLM отключена пользователем - сервер никогда не получит возможности обойти это.

Как работает проверка подлинности Windows:

  • Клиент отправляет обычный HTTP-запрос на сервер
  • Сервер отвечает HTTP-статусом 401 и указывает, что для доступа к ресурсам следует использовать аутентификацию NTLM.
  • Клиент отправляет сообщение NTLM Type1
  • Сервер отвечает сообщением NTLM Type2 с вызовом
  • Клиент отправляет сообщение Type3 с ответом на вызов
  • Сервер отвечает запрошенным фактическим содержимым

Как вы видите, браузер, не поддерживающий NTLM, не перейдет к шагу (3), вместо этого будет отображаться страница IIS с ошибкой 401.

Если у пользователя нет учетных данных, после отмены всплывающего диалогового окна проверки подлинности NTLM не будет продолжаться (3).

Таким образом, у нас нет возможности автоматически перенаправлять пользователей на пользовательскую страницу входа.

Единственная опция здесь - иметь страницу "шлюза", где мы решаем, должен ли пользователь поддерживать NTLM, и если да, перенаправитесь на домашнюю страницу, защищенную NTLM.

И если нет, укажите регистрационную форму и разрешите аутентификацию вручную, введя логин и пароль.

Решение обычно делается на основе IP-адресов пользователей и/или имени хоста, либо путем сопоставления диапазонов IP-адресов, либо путем проверки таблицы предопределенных IP-адресов.

4b9b3361

Ответ 1

Эта статья может заставить вас указать в правильном направлении. В основном у вас есть два приложения в двух виртуальных каталогах под одним и тем же именем хоста. В одном приложении используется проверка подлинности с помощью форм, в Windows используется Windows. Тот, который использует проверку подлинности Windows, создает допустимый файл cookie проверки подлинности и перенаправляется во второй виртуальный каталог.

Аутентификация смешанного режима ASP.NET

Ответ 2

У меня есть эта точная настройка в процессе производства, я настраиваю свой портал на использование FormsAuth и написали функцию, которая заставляет IP-адреса посетителей искать учетную запись пользователя, входящую в этот IP/ПК. Используя имя, которое я нахожу (например, DOMAIN\user), я проверяю, что домен соответствует моему домену, и что имя пользователя/учетная запись действительны в моем поставщике FormsAth, используя Membership.GetUser(<user>). Если этот вызов возвращает совпадение, а пользователь IsApproved, я создаю FormsAuthenticationTicket и cookie для пользователя. У меня есть 400 человек в сети, и это работает отлично, единственные компьютеры, которые все еще находятся в системе (1. Пользователи без учетных записей на моем портале, 2. Несколько пользователей MAC/Linux, 3. Мобильные пользователи, которые не загрузились в сети и с помощью групповой политики их брандмауэр был высоким).

Ловушка для этого решения заключается в том, что для запроса пользовательского ПК требуется олицетворение учетной записи администратора домена, и вы используете неуправляемый код netapi32.dll.. p >

Вот код, который я использую (внешние вызовы функций не предоставляются, для краткости). Я попытался немного упростить это, так как у меня есть LOTS внешних вызовов.

string account = String.Empty;
string domain = String.Empty;
string user = String.Empty;


ImpersonateUser iu = new ImpersonateUser();  //Helper that Enabled Impersonation
if (iu.impersonateValidUser(StringHelper.GetAppSetting("DomainAccount"), StringHelper.GetAppSetting("DomainName"), StringHelper.GetEncryptedAppSetting("DomainAccountPassword")))
{
    NetWorkstationUserEnum nws = new NetWorkstationUserEnum(); //Wrapper for netapi32.dll (Tested on Vista, XP, Win2K, Win2K3, Win2K8)
    string host = nws.DNSLookup(Request.UserHostAddress); // netapi32.dll requires a host name, not an IP address

    string[] users = nws.ScanHost(host); // Gets the users/accounts logged in

    if (nws.ScanHost(host).Length > 0)
    {
        string workstationaccount = string.Empty;

        if (host.IndexOf('.') == -1)  // Pick which account to use, I have 99.9% success with this logic (only time doesn't work is when you run a interactive process as a admin e.g. Run As <process>).
        {
            workstationaccount = String.Format("{0}\\{1}$",StringHelper.GetAppSetting("DomainName"), host).ToUpper();
        }
        else
        {
            workstationaccount = String.Format("{0}\\{1}$", StringHelper.GetAppSetting("DomainName"), host.Substring(0, host.IndexOf('.'))).ToUpperInvariant();
        }

        account = users[users.Length - 1].Equals(workstationaccount) ? users[0] : users[users.Length - 1];

        domain = account.Substring(0, account.IndexOf("\\"));
        user = account.Substring(account.IndexOf("\\") + 1,
                                 account.Length - account.IndexOf("\\") - 1);
    }

    iu.undoImpersonation(); // Disable Impersonation
}

Теперь, используя учетную запись, которую мы захватили в первой функции/процессе, мы теперь пытаемся проверить и решить, следует ли нам показывать логин или автоматический вход пользователя.

MembershipUser membershipUser = Membership.GetUser(user);

if (membershipUser != null && membershipUser.IsApproved)
{
    string userRoles = string.Empty;  // Get all their roles
    FormsAuthenticationUtil.RedirectFromLoginPage(user, userRoles, true); // Create FormsAuthTicket + Cookie + 
}

Я написал сообщение в блоге об этом давным-давно, вот ссылка на обертку для netapi32.dll и моего помощника олицетворения, который я представил в сообщении Загрузка исходного кода

Ответ 3

У вас не может быть NTLM и FormsAuthentication в одном приложении ASP.NET. Вам понадобятся два разных приложения в отдельных виртуальных каталогах.