Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

음... 요즘 devpia에서 Q&A를 하다 보니, 다소 기초적인 내용들을 올리게 되는군요. ^^

그나저나, 너무 빈번한 질문들에 대해서 매번 타자 치기도 그렇고, 간단한 말로 끝내는 것도 질문한 분께 예의가 아닌 것 같아서, 아예 이런 식으로 제 홈피에 정리해 봅니다.

암튼, 아래와 같은 오류가 나는 경우가 있습니다. 이런 부분은 사실 .NET 보안과 Windows의 보안이 다르기 때문에 발생하게 됩니다.


'/KR_KORITECH_03_31' 응용 프로그램에 서버 오류가 있습니다.


레지스트리 키 HKEY_CLASSES_ROOT\... 에 대한 액세스가 거부되었습니다.

설명: 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 스택 추적을 검토하여 발생한 오류 및 코드에서 오류가 발생한 위치에 대한 자세한 정보를 확인하십시오.

예외 정보: System.UnauthorizedAccessException: 레지스트리 키 HKEY_CLASSES_ROOT\... 에 대한 액세스가 거부되었습니다.

ASP.NET에는 요청한 리소스에 액세스할 권한이 없습니다. ASP.NET 요청 ID에 리소스 액세스 권한을 부여하십시오. ASP.NET에는 응용 프로그램이 가장하지 않을 때 사용되는 기본 프로세스 ID(일반적으로 IIS 5에서는 {MACHINE}\ASPNET, IIS 6에서는 Network Service)가 있습니다. 응용 프로그램이 <identity impersonate="true"/>를 통해 가장하고 있는 경우에는 ID가 익명 사용자(일반적으로 IUSR_MACHINENAME) 또는 인증된 요청 사용자가 됩니다.

파일에 대한 쓰기 권한을 ASP.NET에 부여하려면 탐색기에서 파일을 마우스 오른쪽 단추로 클릭하고 [속성]을 선택한 다음 [보안] 탭을 선택합니다. [추가]를 클릭하여 적절한 사용자나 그룹을 추가합니다. ASP.NET 계정을 강조 표시한 다음 원하는 액세스를 선택합니다.

소스 오류:

줄 200:			string chk5="";
줄 201:
줄 202:			using (....FileUpload fileUpload = new ....FileUpload())
줄 203:			{
줄 204:

소스 파일: c:\inetpub\wwwroot\kr_koritech_03_31\admin\pr\pr_news_write.aspx.cs    줄: 202

스택 추적:

[UnauthorizedAccessException: 레지스트리 키 HKEY_CLASSES_ROOT\... 에 대한 액세스가 거부되었습니다.]
   Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str) +74
   Microsoft.Win32.RegistryKey.CreateSubKey(String subkey) +503
   System.Runtime.InteropServices.RegistrationServices.RegisterManagedType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion) +216
   System.Runtime.InteropServices.RegistrationServices.RegisterAssembly(Assembly assembly, AssemblyRegistrationFlags flags) +258
   System.EnterpriseServices.RegistrationDriver.ClassicRegistration(Assembly asm)

[RegistrationException: 'TestModule.NET, Version=3.0.3.0, Culture=neutral, PublicKeyToken=d71d611ccd9cc3c0' 어셈블리를 등록하지 못했습니다.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +264
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +877
   System.EnterpriseServices.RegistrationHelperTx.InstallAssemblyFromConfig(RegistrationConfig& regConfig, Object sync)
   System.EnterpriseServices.RegistrationHelper.TryTransactedInstall(RegistrationConfig regConfig)
   System.EnterpriseServices.RegistrationHelper.InstallAssemblyFromConfig(RegistrationConfig& regConfig)
   System.EnterpriseServices.RegistrationHelper.InstallAssembly(String assembly, String& application, String partition, String& tlb, InstallationFlags installFlags)
   System.EnterpriseServices.RegistrationHelper.InstallAssembly(String assembly, String& application, String& tlb, InstallationFlags installFlags)
   System.EnterpriseServices.RegistrationHelper.System.EnterpriseServices.Thunk.IThunkInstallation.DefaultInstall(String asm)
   System.EnterpriseServices.Thunk.Proxy.RegisterAssembly(Assembly assembly)
   System.EnterpriseServices.Thunk.Proxy.LazyRegister(Guid id, Type serverType, Boolean checkCache)
   System.EnterpriseServices.Thunk.Proxy.CoCreateObject(Type serverType, Boolean bQuerySCInfo, Boolean& bIsAnotherProcess, String& uri)
   System.EnterpriseServices.ServicedComponentProxyAttribute.CreateInstance(Type serverType)
   System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(Type serverType, Object[] props, Boolean bNewObj) +74
   koritech.admin.pr.pr_news_write.InsertData() in c:\inetpub\wwwroot\kr_koritech_03_31\admin\pr\pr_news_write.aspx.cs:202
   koritech.admin.pr.pr_news_write.ImageButton1_Click(Object sender, ImageClickEventArgs e) in c:\inetpub\wwwroot\kr_koritech_03_31\admin\pr\pr_news_write.aspx.cs:340
   System.Web.UI.WebControls.ImageButton.OnClick(ImageClickEventArgs e)
   System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   System.Web.UI.Page.ProcessRequestMain()


버전 정보: Microsoft .NET Framework 버전:1.1.4322.2032; ASP.NET 버전:1.1.4322.2032 SP.NET Version:1.1.4322.2300

위의 오류 화면은, 한마디로 .NET COM+ 개체가 레지스트리에 자신을 등록해야 하는데 해당 레지스트리 키를 만들 수 있는 권한이 없다는 것입니다. 아시는 것처럼, 일반적으로 Registry는 상당히 중요한 시스템 리소스입니다. 아마도 이 글 읽으시는 분들 중에는 레지스트리를 잘못 편집했다가 시스템이 엉망이 된 경우도 있으실 텐데요. 따라서, 레지스트리를 함부로 편집하지 못하도록 레지스트리 자체에도 Win32 보안이 적용되어져 있습니다.

실제로 COM+ 개체의 경우, 일반적으로 HKEY_CLASSES_ROOT 하위에 자신을 등록하려고 하는데요. 아래의 그림에서 보는 것처럼, 보안이 제법 강력하게 적용되어져 있습니다.

HKEY_CLASSES_ROOT 보안

살펴 보시면, "쓰기 권한"은 "Administrators", "SYSTEM"만이 가능하며, 나머지는 읽기 권한일 뿐입니다.

자, 이제 문제가 분명해 진것 같습니다. "액세스가 거부되었습니다."가 나오는 원인은 ASP.NET 작업자 프로세스가 (등록 코드를 실행하는 스레드까지도) "Administrators", "SYSTEM"에 속해 있지 않기 때문에 발생하는 것입니다.

그렇다면, 답은 2가지가 있을 수 있겠습니다.
첫 번째, HKEY_CLASSES_ROOT 권한에 현재의 ASP.NET 작업자 프로세스의 계정을 추가하는 것입니다. 해당 계정은 "작업관리자" 등을 통해서 확인할 수 있지요. 대개의 경우, IIS 5.0에서는 "ASPNET" 계정이고, IIS 6.0에서는 "Network Service" 계정입니다. 따라서, 그에 맞게 regedit.exe를 이용해서 HKEY_CLASSES_ROOT에 권한을 추가해 주면 됩니다.

두 번째, ASP.NET 작업자 프로세스 계정을 "Administrators"에 가입된 계정이나, "SYSTEM" 계정으로 설정하는 것입니다. 이것 역시, IIS 버전에 따라 틀린데요. IIS 5.0에서는 .NET Framework이 설치되어져 있는 폴더의 Machine.config에서 processModel 요소를 수정해 주면 됩니다. 일례로, .NET 1.1의 경우에,

C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config

위의 파일을 열어서,

<processModel enable="true" ..... userName="SYSTEM" password="AutoGenerate" ... maxIoThreads="20" />

위와 같이 userName 속성에 적절한 계정을 넣어주시면 됩니다.

IIS 6.0의 경우에는 해당 웹 사이트 또는 가상 디렉토리가 Application Pool의 적용을 받기 때문에 해당 App Pool의 ID 탭에서 계정을 설정해 주시면 됩니다 다음과 같은 화면처럼.

Application Pool 계정 설정


첫 번째 방식과, 두 번째 방식의 장단점을 비교해 보면.

첫 번째의 레지스트리 키에 직접 보안이 낮은 계정을 추가하는 것은 오히려 보안 위험도를 높일 수가 있는 점이 있습니다. 물론, 두 번째의 설정은 오히려 더 보안 위험도가 높을 수 있는 것입니다. 레지스트리 하나 보호하려고 Front-End 단에서 (무작위) 사용자 코드 실행을 담당하는 Web Application의 권한을 높여주는 것이기 때문입니다. 즉, Web Application의 보안에 구멍이 뚫리기 시작하면, 레지스트리 하나 정도로 끝날 문제는 아니라는 거죠.

이런 문제로 인해, MS에서 제시하는 것은 Web Application을 구동하는 별도의 계정을 만들어서 적절한 권한만을 주는 것입니다. 하지만, 애플리케이션을 작성하다 보면, 도저히 일반 계정으로는 일일이 보안 설정을 다 못하는 경우가 있습니다. 일반 계정 하나 만들어 놓고, 그걸 가지고 필요한 보안 설정을 하다 보면, 결국 Administrator나 SYSTEM 계정과 권한이 비슷한 수위에 올라오게 되는 것인데요.

어쨌든, 선택은 여러분들 또는 그 위의 보안 담당자 및 운영자와 적절하게 상의를 하셔야 할 것이고요.

저에게 물으신다면... 아래와 같이 답하고 싶습니다.
만약, 위와 같이 COM+ 개체 하나 정도의 등록 때문이라면, 첫 번째 및 두 번째 방식을 모두 선택하지 않을 것입니다. 왜냐면, 결국 COM+ 등록은 레지스트리에 최초 한 번만 씌여지면 그만이므로, 한 번의 등록시에만 권한이 있는 사용자로 로그인해서 등록을 시키고, 이후에는 다시 "Network Service" 등의 계정으로 구동을 시킬 것입니다.
[연관 글]






[최초 등록일: ]
[최종 수정일: 6/24/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  [11]  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13377정성태6/22/20237443오류 유형: 867. 파이썬 mysqlclient 2.2.x 설치 시 "Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually" 오류
13376정성태6/21/20233809.NET Framework: 2129. C# - Polly를 이용한 클라이언트 측의 요청 재시도파일 다운로드1
13375정성태6/20/20233477스크립트: 50. Transformers (신경망 언어모델 라이브러리) 강좌 - 2장 코드 실행 결과
13374정성태6/20/20233607오류 유형: 866. 파이썬 - <class 'AttributeError'> module 'flask.json' has no attribute 'JSONEncoder'
13373정성태6/19/20234891오류 유형: 865. 파이썬 - pymssql 설치 관련 오류 정리
13372정성태6/15/20233407개발 환경 구성: 682. SQL Server TLS 통신을 위해 사용되는 키 길이 확인 방법
13371정성태6/15/20233545개발 환경 구성: 681. openssl - 인증서 버전(V1 / V3)
13370정성태6/14/20233682개발 환경 구성: 680. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법 - TLS 1.2 지원
13369정성태6/13/20233495개발 환경 구성: 679. PyCharm(을 비롯해 JetBrains에 속한 여타) IDE에서 내부 Window들의 탭이 없어진 경우
13368정성태6/13/20233639개발 환경 구성: 678. openssl로 생성한 인증서를 SQL Server의 암호화 인증서로 설정하는 방법
13367정성태6/10/20233836오류 유형: 864. openssl로 만든 pfx 인증서를 Windows Server 2016 이하에서 등록 시 "The password you entered is incorrect" 오류 발생
13366정성태6/10/20233603.NET Framework: 2128. C# - 윈도우 시스템에서 지원하는 암호화 목록(Cipher Suites) 나열파일 다운로드1
13365정성태6/8/20233217오류 유형: 863. MODIFY FILE encountered operating system error 112(failed to retrieve text for this error. Reason: 15105)
13364정성태6/8/20234088.NET Framework: 2127. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법 [1]
13363정성태6/7/20233665스크립트: 49. 파이썬 - "Transformers (신경망 언어모델 라이브러리) 강좌" - 1장 2절 코드 실행 결과
13362정성태6/1/20233671.NET Framework: 2126. C# - 서버 측의 요청 제어 (Microsoft.AspNetCore.RateLimiting)파일 다운로드1
13361정성태5/31/20233986오류 유형: 862. Facebook - ASP.NET/WebClient 사용 시 graph.facebook.com/me 호출에 대해 403 Forbidden 오류
13360정성태5/31/20233347오류 유형: 861. WSL/docker - failed to start shim: start failed: io.containerd.runc.v2: create new shim socket
13359정성태5/19/20233648오류 유형: 860. Docker Desktop - k8s 초기화 무한 반복한다면?
13358정성태5/17/20234132.NET Framework: 2125. C# - Semantic Kernel의 Semantic Memory 사용 예제 [1]파일 다운로드1
13357정성태5/16/20233949.NET Framework: 2124. C# - Semantic Kernel의 Planner 사용 예제파일 다운로드1
13356정성태5/15/20234266DDK: 10. Device Driver 테스트 설치 관련 오류 (Code 37, Code 31) 및 인증서 관련 정리
13355정성태5/12/20234209.NET Framework: 2123. C# - Semantic Kernel의 ChatGPT 대화 구현 [1]파일 다운로드1
13354정성태5/12/20234330.NET Framework: 2122. C# - "Use Unicode UTF-8 for worldwide language support" 설정을 한 경우, 한글 입력이 '\0' 문자로 처리
13352정성태5/12/20234038.NET Framework: 2121. C# - Semantic Kernel의 대화 문맥 유지파일 다운로드1
13351정성태5/11/20234494VS.NET IDE: 185. Visual Studio - 원격 Docker container 내에 실행 중인 응용 프로그램에 대한 디버깅 [1]
1  2  3  4  5  6  7  8  9  10  [11]  12  13  14  15  ...