Windows 프로그램을 사용하여 사서함이 포함된 도메인 계정 배치를 성공적으로 만든 적이 있습니다. 그러나 이 코드를 동료 중 한 명(그는 웹 응용 프로그램 개발 담당)에게 제공하고 이를 asp.net으로 마이그레이션했을 때 도메인 생성만 가능했습니다. 계정, 사서함을 만들 수 없습니다. 왜?
우리는 Microsoft 엔지니어에게 문의했고 그는 이것이 asp.net의 권한이 부족하기 때문이라고 말했습니다. asp.net이 성공적으로 생성될 수 있도록 사용자를 시뮬레이션해야 합니다.
Microsoft에서 관련 기사를 발췌했습니다.
IIS 인증 계정 또는 사용자
가장 ASP.NET 응용 프로그램의 모든 페이지에 대한 모든 요청이 수신될 때 Microsoft IIS(인터넷 정보 서비스) 인증 사용자를 가장하려면 이 응용 프로그램 <identity> 태그에 대한 Web.config 파일에 포함해야 합니다. impersonate 속성을 true로 설정합니다. 예:
<identity impersonate="true" />
ASP.NET 응용 프로그램에 대한 모든 요청에 대해 특정 사용자를 가장
ASP.NET 응용 프로그램의 모든 페이지에 대한 모든 요청에 대해 특정 사용자를 가장하려면 userName 및 암호 특성을 지정할 수 있습니다. 예:
<identity impersonate="true" userName="accountname" 비밀번호="password" />
참고: 스레드에서 특정 사용자를 가장하는 프로세스의 ID에는 "운영 체제의 일부로" 권한이 있어야 합니다. 기본적으로 Aspnet_wp.exe 프로세스는 ASPNET이라는 컴퓨터 계정으로 실행됩니다. 그러나 이 계정에는 특정 사용자를 가장하는 데 필요한 권한이 없습니다. 특정 사용자를 가장하려고 하면 오류 메시지가 나타납니다.
이 문제를 해결하려면 다음 방법 중 하나를 사용하십시오.
?
ASPNET 계정(최소 권한의 계정)에 "운영 체제의 일부로 작동" 권한을 부여합니다.
참고: 이 방법으로 문제가 해결될 수도 있지만 Microsoft에서는 이 방법을 권장하지 않습니다.
•
Machine.config 파일의 <processModel> 구성 섹션에서 Aspnet_wp.exe 프로세스가 실행되는 계정을 시스템 계정으로 변경합니다.
코드에서 인증된 사용자
가장 코드의 특정 부분을 실행할 때만 인증된 사용자(User.Identity)를 가장하려면 다음 코드를 사용하면 됩니다. 이 방법을 사용하려면 인증 사용자 ID가 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()
'여기에 인증 사용자의 보안 컨텍스트에서 실행되는 코드를 삽입하세요.
impersonationContext.Undo()
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//인증하는 사용자의 보안 컨텍스트에서 실행되는 코드를 여기에 삽입하세요.
impersonationContext.Undo();
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();
//인증하는 사용자의 보안 컨텍스트에서 실행되는 코드를 여기에 삽입하세요.
impersonationContext.Undo();
코드에서 특정 사용자
가장 코드의 특정 부분을 실행할 때만 특정 사용자를 가장하려면 다음 코드를 사용합니다.
Visual Basic .NET
<%@ Page Language="VB" %>
<%@ 네임스페이스 가져오기 = "System.Web" %>
<%@ 네임스페이스 가져오기 = "System.Web.Security" %>
<%@ 네임스페이스 가져오기 = "System.Security.Principal" %>
<%@ 네임스페이스 가져오기 = "System.Runtime.InteropServices" %>
<스크립트 runat=서버>
Dim LOGON32_LOGON_INTERACTIVE 정수 = 2
Dim LOGON32_PROVIDER_DEFAULT 정수 = 0
희미한 impersonationContext As WindowsImpersonationContext
LogonUserA Lib "advapi32.dll" 함수 선언(ByVal lpszUsername As String, _
ByVal lpszDomain 문자열, _
ByVal lpszPassword를 문자열로, _
ByVal dwLogonType은 정수, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) 정수로
자동 함수 DuplicateToken Lib "advapi32.dll"( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) 정수로
자동 기능 RevertToSelf Lib "advapi32.dll"()을 길게 선언
자동 함수 CloseHandle Lib "kernel32.dll"(ByVal 핸들 As IntPtr)을 길게 선언
공개 하위 페이지_Load(ByVal s As Object, ByVal e As EventArgs)
If impersonateValidUser("username", "domain", "password") 그런 다음
'특정 사용자의 보안 컨텍스트에서 실행되는 코드를 여기에 삽입하세요.
실행 취소가장()
또 다른
'귀하의 가장이 실패했습니다. 따라서 여기에 안전 장치 메커니즘을 포함하십시오.
종료 조건
서브 끝
개인 함수 impersonateValidUser(ByVal userName As String, _
ByVal 도메인을 문자열로, ByVal 비밀번호를 문자열로) 부울로
희미한 tempWindowsIdentity를 WindowsIdentity로 사용
Dim 토큰 As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
impersonateValidUser = 거짓
RevertToSelf() 다음인 경우
LogonUserA(사용자 이름, 도메인, 비밀번호, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, 토큰) <> 0 그런 다음
DuplicateToken(token, 2, tokenDuplicate) <> 0인 경우
tempWindowsIdentity = 새 WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
impersonationContext가 아무것도 아닌 경우
impersonateValidUser = 참
종료 조건
종료 조건
종료 조건
종료 조건
tokenDuplicate.Equals(IntPtr.Zero)가 아닌 경우
CloseHandle(토큰중복)
종료 조건
그렇지 않은 경우 token.Equals(IntPtr.Zero) 그런 다음
CloseHandle(토큰)
종료 조건
기능 종료
비공개 하위 undoImpersonation()
impersonationContext.Undo()
서브 끝
</script>
비주얼 C# .NET
<%@ 페이지 언어="C#"%>
<%@ 네임스페이스 가져오기 = "System.Web" %>
<%@ 네임스페이스 가져오기 = "System.Web.Security" %>
<%@ 네임스페이스 가져오기 = "System.Security.Principal" %>
<%@ 네임스페이스 가져오기 = "System.Runtime.InteropServices" %>
<스크립트 runat=서버>
공개 const int LOGON32_LOGON_INTERACTIVE = 2;
공개 const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
공개 정적 extern int LogonUserA(String lpszUserName,
문자열 lpszDomain,
문자열 lpszPassword,
int dwLogonType,
int dwLogonProvider,
참조 IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
공개 정적 extern int DuplicateToken(IntPtr hToken,
정수 가장 레벨,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
공개 정적 extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
공개 정적 extern bool CloseHandle(IntPtr 핸들);
공개 무효 Page_Load(Object s, EventArgs e)
{
if(impersonateValidUser("사용자 이름", "도메인", "비밀번호"))
{
//특정 사용자의 보안 컨텍스트에서 실행되는 코드를 여기에 삽입하세요.
undoImpersonation();
}
또 다른
{
//가장에 실패했습니다. 따라서 여기에 오류 방지 메커니즘을 포함하세요.
}
}
private bool impersonateValidUser(문자열 사용자 이름, 문자열 도메인, 문자열 비밀번호)
{
WindowsIdentity tempWindowsIdentity;
IntPtr 토큰 = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if(RevertToSelf())
{
if(LogonUserA(사용자 이름, 도메인, 비밀번호, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, 참조 토큰) != 0)
{
if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(토큰);
CloseHandle(tokenDuplicate);
사실을 반환;
}
}
}
}
if(token!= IntPtr.Zero)
CloseHandle(토큰);
if(tokenDuplicate!=IntPtr.Zero)
CloseHandle(tokenDuplicate);
거짓을 반환;
}
개인 무효 실행 취소()
{
impersonationContext.Undo();
}
</script>
Visual J# .NET
<%@ 페이지 언어="VJ#" %>
<%@ 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;
/** @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 DuplicateToken(System.IntPtr hToken,
정수 가장 수준,
System.IntPtr[] hNewToken);
/** @attribute DllImport("kernel32.dll",CharSet=CharSet.Auto) */
공개 정적 네이티브 부울 CloseHandle(System.IntPtr[] 핸들);
/** @attribute DllImport("advapi32.dll",
CharSet=CharSet.Auto,SetLastError=true) */
공개 정적 네이티브 부울 RevertToSelf();
공개 무효 Page_Load(Object s, System.EventArgs e)
{
if(impersonateValidUser("사용자 이름", "도메인", "비밀번호"))
{
//특정 사용자의 보안 컨텍스트에서 실행되는 코드를 여기에 삽입하세요.
undoImpersonation();
}
또 다른
{
//가장에 실패했습니다. 따라서 여기에 오류 방지 메커니즘을 포함하세요.
}
}
private boolean impersonateValidUser(문자열 userName, 문자열 도메인, 문자열 비밀번호)
{
WindowsIdentity tempWindowsIdentity;
System.IntPtr[] 토큰 = new System.IntPtr[1];
System.IntPtr[] tokenDuplicate = new System.IntPtr[1];
if(RevertToSelf())
{
if(LogonUserA(사용자 이름, 도메인, 비밀번호, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, 토큰) != 0)
{
if(DuplicateToken(token[0], 2, tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate[0]);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(tokenDuplicate);
CloseHandle(토큰);
사실을 반환;
}
}
}
}
if(!token[0].Equals(System.IntPtr.Zero))
CloseHandle(토큰);
if(!tokenDuplicate[0].Equals(System.IntPtr.Zero))
CloseHandle(tokenDuplicate);
거짓을 반환;
}
개인 무효 실행 취소()
{
impersonationContext.Undo();
}
</script>
참고: 스레드에서 특정 사용자를 가장하는 프로세스의 ID에는 "운영 체제의 일부로" 권한이 있어야 합니다. 기본적으로 Aspnet_wp.exe 프로세스는 ASPNET이라는 컴퓨터 계정으로 실행됩니다. 그러나 이 계정에는 특정 사용자를 가장하는 데 필요한 권한이 없습니다. 특정 사용자를 가장하려고 하면 오류 메시지가 나타납니다.
이 문제를 해결하려면 다음 방법 중 하나를 사용하십시오.
?
ASPNET 계정에 "운영 체제의 일부로 작동" 권한을 부여합니다.
•
Machine.config 파일의 <processModel> 구성 섹션에서 Aspnet_wp.exe 프로세스가 실행되는 계정을 시스템 계정으로 변경합니다.