ASP.NET - System.Security.SecurityException: 'Requested registry access is not allowed.'
예전에도 언급했던 오류인데,
IIS Express에서 COM+ 사용 시 SecurityException - "Requested registry access is not allowed" 발생
; https://www.sysnet.pe.kr/2/0/1726
ASP.NET 응용 프로그램을 IIS Express에서 디버깅할 때 "Requested registry access is not allowed" 오류 발생
; https://www.sysnet.pe.kr/2/0/1593
이번엔 소스코드를 들여다보며 정리했기 때문에 기록을 남깁니다.
IIS에서 .NET Framework 4.8용의 ASP.NET 웹 프로젝트를 "System.Security.SecurityException" 예외에 대해 "thrown" 옵션을 넣고 실행하면 이런 오류가 발생할 수 있습니다. (개인적으로 가능한
모든 오류를 thrown으로 둬서 모르고 지나가는 예외를 최대한 없게 하자는 원칙을 가지고 있습니다.)
System.Security.SecurityException
HResult=0x8013150A
Message=Requested registry access is not allowed.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource) in f:\dd\ndp\clr\src\BCL\system\throwhelper.cs:line 107
This exception was originally thrown at this call stack:
System.ThrowHelper.ThrowSecurityException(System.ExceptionResource) in throwhelper.cs
이때의 호출 스택에 따라,
> mscorlib.dll!System.ThrowHelper.ThrowSecurityException(System.ExceptionResource resource) Line 70 C# Symbols loaded.
mscorlib.dll!Microsoft.Win32.RegistryKey.OpenSubKey(string name, bool writable) Line 827 C# Symbols loaded.
System.Web.dll!System.Web.Util.Misc.GetAspNetRegValue(string subKey, string valueName = null, object defaultValue = null) Line 179 C# Symbols loaded.
System.Web.dll!System.Web.Compilation.CompilationMutex.CompilationMutex(string name = "CL9dcc5588", string comment = "CompilationLock for /") Line 23 C# Symbols loaded.
System.Web.dll!System.Web.Compilation.CompilationLock.CompilationLock() Line 13 C# Symbols loaded.
[Native to Managed Transition] Annotated Frame
[Managed to Native Transition] Annotated Frame
...[생략]...
GetAspNetRegValue 메서드를 보면 아래와 같이 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0" 하위 키를 열려고 시도하는데,
[RegistryPermission(SecurityAction.LinkDemand, Unrestricted = true)]
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
internal static object GetAspNetRegValue(string subKey, string valueName, object defaultValue)
{
try
{
using RegistryKey registryKey = OpenAspNetRegKey(subKey);
if (registryKey == null)
{
return defaultValue;
}
return registryKey.GetValue(valueName, defaultValue);
}
catch
{
return defaultValue;
}
}
internal static RegistryKey OpenAspNetRegKey(string subKey)
{
string text = VersionInfo.SystemWebVersion; // .NET Framework 4.8의 경우: text == "4.0.30319.0"
if (!string.IsNullOrEmpty(text))
{
int num = text.LastIndexOf('.');
if (num > -1)
{
text = text.Substring(0, num + 1) + "0";
}
}
string text2 = "Software\\Microsoft\\ASP.NET\\" + text;
if (subKey != null)
{
text2 = text2 + "\\" + subKey; // text2 == "SOFTWARE\Microsoft\ASP.NET\4.0.30319.0" + subKey
}
return Registry.LocalMachine.OpenSubKey(text2);
}
이때 전달된 subKey 값을 찾아보면,
internal CompilationMutex(string name, string comment)
{
string text = (string)Misc.GetAspNetRegValue("CompilationMutexName", null, null);
if (text != null)
{
_name = _name + "Global\\" + name + "-" + text;
}
else
{
_name = _name + "Local\\" + name;
}
_comment = comment;
_mutexHandle = new HandleRef(this, UnsafeNativeMethods.InstrumentedMutexCreate(_name));
if (_mutexHandle.Handle == IntPtr.Zero)
{
throw new InvalidOperationException(SR.GetString("CompilationMutex_Create"));
}
}
결국 "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0\CompilationMutexName" 경로임을 알 수 있습니다. 따라서, 이번에도 역시 해당 레지스트리 키에 대해 Read 권한을 주는 것으로 해결할 수 있습니다.
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]