Однажды я успешно создал группу учетных записей домена с почтовыми ящиками с помощью программы Windows. Однако, когда я передал этот код одной из моих коллег (она отвечала за разработку веб-приложений) и перенес его на asp.net, он смог только создать домен. аккаунт, не могу создать почтовый ящик. Почему?
Мы проконсультировались с инженером Microsoft, и он сказал нам, что это связано с недостаточными разрешениями asp.net. Нам следует смоделировать пользователя в asp.net, чтобы его можно было успешно создать.
Я привел соответствующие статьи от Microsoft:
Олицетворение учетной записи или пользователя, прошедшего проверку подлинности IIS.
Чтобы олицетворять пользователя, прошедшего проверку подлинности Microsoft Internet Information Services (IIS), при получении каждого запроса для каждой страницы в приложении ASP.NET, необходимо включить в файл Web.config для этого приложения тег <identity>. и установите для атрибута impersonate значение true. Например:
<identity impersonate="true" />
Олицетворение конкретного пользователя для всех запросов к приложению ASP.NET
Чтобы олицетворять конкретного пользователя для всех запросов на всех страницах приложения ASP.NET, вы можете указать атрибут userName и пароль. Например:
<identity impersonate="true" userName="имя учетной записи" пароль="пароль" />
Примечание. Идентификатор процесса, который олицетворяет конкретного пользователя в потоке, должен иметь разрешение «Как часть операционной системы». По умолчанию процесс Aspnet_wp.exe запускается под учетной записью компьютера с именем ASPNET. Однако эта учетная запись не имеет необходимых разрешений, чтобы выдавать себя за конкретного пользователя. Если вы попытаетесь выдать себя за конкретного пользователя, появится сообщение об ошибке.
Чтобы решить эту проблему, используйте один из следующих методов:
•
Предоставьте учетной записи ASPNET (учетной записи с наименьшими привилегиями) разрешение «Действовать как часть операционной системы».
Примечание. Хотя этот метод может решить проблему, Microsoft не рекомендует его.
•
В разделе конфигурации <processModel> файла Machine.config измените учетную запись, под которой запускается процесс Aspnet_wp.exe, на системную учетную запись.
Олицетворение аутентифицированного пользователя в коде
Чтобы олицетворять аутентифицированного пользователя (User.Identity) только при выполнении определенной части кода, вы можете использовать следующий код. Для этого метода требуется, чтобы идентификатор пользователя проверки подлинности имел тип WindowsIdentity.
Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext
Уменьшить текущийWindowsIdentity как System.Security.Principal.WindowsIdentity
currentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()
«Вставьте сюда свой код, который работает в контексте безопасности аутентифицирующего пользователя.
олицетворениеКонтекст.Отменить()
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
олицетворениеКонтекст =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Вставьте сюда свой код, который работает в контексте безопасности аутентифицирующего пользователя.
олицетворениеКонтекст.Отменить();
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
олицетворениеКонтекст =
((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();
//Вставьте сюда свой код, который работает в контексте безопасности аутентифицирующего пользователя.
олицетворениеКонтекст.Отменить();
Олицетворение конкретного пользователя в коде
Чтобы олицетворять конкретного пользователя только при выполнении определенных частей кода, используйте следующий код:
Visual Basic .NET
<%@ Page Language="VB" %>
<%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %>
<скрипт runat=сервер>
Уменьшить LOGON32_LOGON_INTERACTIVE как целое число = 2
Уменьшить LOGON32_PROVIDER_DEFAULT как целое число = 0
Тусклый контекст олицетворения как WindowsImpersonationContext
Объявить функцию LogonUserA Lib «advapi32.dll» (ByVal lpszUsername As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType Как целое число, _
ByVal dwLogonProvider Как целое число, _
ByRef phToken As IntPtr) Как целое число
Объявить автоматическую функцию DuplateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel как целое число, _
ByRef DuplateTokenHandle As IntPtr) Как целое число
Объявить автоматическую функцию RevertToSelf Lib "advapi32.dll" () как можно дольше
Объявить автоматическую функцию CloseHandle Lib "kernel32.dll" (дескриптор ByVal как IntPtr) как длинный
Public Sub Page_Load (ByVal как объект, ByVal e как EventArgs)
Если impersonateValidUser("имя пользователя", "домен", "пароль") Тогда
«Вставьте сюда свой код, который работает в контексте безопасности конкретного пользователя.
отменитьОлицетворение()
Еще
«Ваше выдача себя за другое лицо не удалась. Поэтому включите сюда отказоустойчивый механизм.
Конец, если
Конец субтитра
Частная функция impersonateValidUser (ByVal userName As String, _
Домен ByVal Как строка, пароль ByVal Как строка) Как логическое значение
Dim tempWindowsIdentity как WindowsIdentity
Тусклый токен As IntPtr = IntPtr.Zero
Тусклый токенДублировать как IntPtr = IntPtr.Zero
impersonateValidUser = Ложь
Если RevertToSelf() Тогда
Если LogonUserA(имя пользователя, домен, пароль, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, токен) <> 0 Тогда
Если DuplicationToken(token, 2, tokenDuplate) <> 0 Тогда
tempWindowsIdentity = Новый идентификатор Windows (tokenDuplate)
олицетворениеКонтекст = tempWindowsIdentity.Impersonate()
Если не контекст олицетворения, то это ничто.
impersonateValidUser = Истина
Конец, если
Конец, если
Конец, если
Конец, если
Если Не tokenDuulate.Equals(IntPtr.Zero), Тогда
CloseHandle (токенДупликат)
Конец, если
Если Не токен.Равно(IntPtr.Zero) Тогда
CloseHandle(токен)
Конец, если
Конечная функция
Частная подпрограмма отмены олицетворения()
олицетворениеКонтекст.Отменить()
Конец субтитра
</script>
Visual C# .NET
<%@ Page Language="C#"%>
<%@ Import Namespace = "System.Web" %>
<%@ Import Namespace = "System.Web.Security" %>
<%@ Import Namespace = "System.Security.Principal" %>
<%@ Import Namespace = "System.Runtime.InteropServices" %>
<скрипт runat=сервер>
общественная константа int LOGON32_LOGON_INTERACTIVE = 2;
общественная константа int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
public static extern int LogonUserA (String lpszUserName,
Строка lpszDomain,
Строка lpszPassword,
int dwLogonType,
int dwLogonProvider,
ссылка IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
общественный статический extern int DuplateToken (IntPtr hToken,
int олицетворениеLevel,
ссылка IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public static extern bool CloseHandle (дескриптор IntPtr);
public void Page_Load (Object s, EventArgs e)
{
if(impersonateValidUser("имя пользователя", "домен", "пароль"))
{
//Вставьте сюда свой код, который работает в контексте безопасности конкретного пользователя.
отменитьОлицетворение();
}
еще
{
//Ваше олицетворение не удалось, поэтому включите сюда отказоустойчивый механизм.
}
}
Private bool impersonateValidUser (String имя пользователя, строковый домен, строковый пароль)
{
WindowsIdentity tempWindowsIdentity;
Токен IntPtr = IntPtr.Zero;
IntPtr tokenDuulate = IntPtr.Zero;
если (RevertToSelf())
{
if(LogonUserA(имя пользователя, домен, пароль, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, токен ссылки) != 0)
{
if(DuulateToken(token, 2, ref tokenDuplate) != 0)
{
tempWindowsIdentity = новый WindowsIdentity (tokenDuulate);
олицетворениеКонтекст = tempWindowsIdentity.Impersonate();
если (impersonationContext!= ноль)
{
CloseHandle (токен);
CloseHandle (токенДупликат);
вернуть истину;
}
}
}
}
если(токен!= IntPtr.Zero)
CloseHandle (токен);
если (токенДупликат! = IntPtr.Zero)
CloseHandle (токенДупликат);
вернуть ложь;
}
частная пустота отменитьОлицетворение()
{
олицетворениеКонтекст.Отменить();
}
</script>
Visual J# .NET
<%@ Page Language="VJ#" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Web.Security" %>
<%@ Import Namespace="System.Security.Principal" %>
<%@ Import Namespace="System.Runtime.InteropServices" %>
<скрипт runat=сервер>
общедоступный статический интервал LOGON32_LOGON_INTERACTIVE = 2;
общедоступный статический интервал LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
/** @attribute DllImport("advapi32.dll") */
общедоступный статический собственный int LogonUserA (String lpszUserName,
Строка lpszDomain,
Строка lpszPassword,
int dwLogonType,
int dwLogonProvider,
System.IntPtr[] phToken);
/** @attribute DllImport("advapi32.dll",
CharSet=CharSet.Auto, SetLastError=true) */
общедоступный статический собственный int DuplicationToken(System.IntPtr hToken,
int олицетворениеLevel,
System.IntPtr[] hNewToken);
/** @attribute DllImport("kernel32.dll",CharSet=CharSet.Auto) */
общедоступное статическое собственное логическое значение CloseHandle(System.IntPtr[] handle);
/** @attribute DllImport("advapi32.dll",
CharSet=CharSet.Auto,SetLastError=true) */
общедоступное статическое собственное логическое значение RevertToSelf();
public void Page_Load(Object s, System.EventArgs e)
{
if(impersonateValidUser("имя пользователя", "домен", "пароль"))
{
//Вставьте сюда свой код, который работает в контексте безопасности конкретного пользователя.
отменитьОлицетворение();
}
еще
{
//Ваше олицетворение не удалось, поэтому включите здесь отказоустойчивый механизм.
}
}
частное логическое значение impersonateValidUser (имя пользователя String, домен String, пароль String)
{
WindowsIdentity tempWindowsIdentity;
Токен System.IntPtr[] = новый System.IntPtr[1];
System.IntPtr[] tokenDuplate = новый System.IntPtr[1];
если (RevertToSelf())
{
if(LogonUserA(имя пользователя, домен, пароль, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, токен) != 0)
{
if(DuulateToken(token[0], 2, tokenDuplate) != 0)
{
tempWindowsIdentity = новый WindowsIdentity (tokenDuplate [0]);
олицетворениеКонтекст = tempWindowsIdentity.Impersonate();
если (impersonationContext!= ноль)
{
CloseHandle (токенДупликат);
CloseHandle (токен);
вернуть истину;
}
}
}
}
if(!token[0].Equals(System.IntPtr.Zero))
CloseHandle (токен);
if(!tokenDuulate[0].Equals(System.IntPtr.Zero))
CloseHandle (токенДупликат);
вернуть ложь;
}
частная пустота отменитьОлицетворение()
{
олицетворениеКонтекст.Отменить();
}
</скрипт>
Примечание. Идентификатор процесса, который олицетворяет конкретного пользователя в потоке, должен иметь разрешение «Как часть операционной системы». По умолчанию процесс Aspnet_wp.exe запускается под учетной записью компьютера с именем ASPNET. Однако эта учетная запись не имеет необходимых разрешений, чтобы выдавать себя за конкретного пользователя. Если вы попытаетесь выдать себя за конкретного пользователя, появится сообщение об ошибке.
Чтобы решить эту проблему, используйте один из следующих методов:
•
Предоставьте учетной записи ASPNET разрешение «Действовать как часть операционной системы».
•
В разделе конфигурации <processModel> файла Machine.config измените учетную запись, под которой запускается процесс Aspnet_wp.exe, на системную учетную запись.