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