企业库的日志记录应用程序块中的LogEntry.cs中存在以下代码:
private bool UnmanagedCodePermissionAvailable
{
get
{
if (!unmanagedCodePermissionAvailableInitialized)
{
// check whether the unmanaged code permission is available to avoid three potential stack walks
bool internalUnmanagedCodePermissionAvailable = false;
SecurityPermission unmanagedCodePermission =
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
// avoid a stack walk by checking for the permission on the current assembly. this is safe because there are no
// stack walk modifiers before the call.
if (SecurityManager.IsGranted(unmanagedCodePermission))
{
try
{
unmanagedCodePermission.Demand();
internalUnmanagedCodePermissionAvailable = true;
}
catch (SecurityException)
{ }
}
this.UnmanagedCodePermissionAvailable =
internalUnmanagedCodePermissionAvailable;
}
return this.unmanagedCodePermissionAvailable;
}
set
{
this.unmanagedCodePermissionAvailable = value;
unmanagedCodePermissionAvailableInitialized = true;
}
}
在进行多次P / Invoke调用以检索各种信息以帮助填写LogEntry结构之前调用该函数。如果“UnmanagedCodePermission”不可用,则相应的LogEntry属性将设置为指示此类的字符串(“XXX不可用”)。
例如,LogEntry想要获取Win32线程ID,它使用Win / C调用来调用Win32函数GetCurrentThreadId来获取它。在调用GetCurrentThreadId之前,它会检查“unamanged code permission”是否可用。如果是这样,它会进行呼叫,如果不是,则不会。像这样:
private void InitializeWin32ThreadId()
{
if (this.UnmanagedCodePermissionAvailable)
{
try
{
this.Win32ThreadId = LogEntryContext.GetCurrentThreadId();
}
catch (Exception e)
{
this.Win32ThreadId = string.Format(
CultureInfo.CurrentCulture,
Properties.Resources.IntrinsicPropertyError,
e.Message);
}
}
else
{
this.Win32ThreadId = string.Format(CultureInfo.CurrentCulture,
Properties.Resources.IntrinsicPropertyError,
Properties.Resources.
LogEntryIntrinsicPropertyNoUnmanagedCodePermissionError);
}
}
据我所知,无可否认,由于安全性/权限/信任,调用非托管代码(例如P / Invoke)并不总是可行的。检查是否可以进行非托管代码调用,可以统一保护所有非托管调用。
当我编译此代码时,我会在此行收到警告:
if (SecurityManager.IsGranted(unmanagedCodePermission))
这是警告:
System.Security.SecurityManager.IsGranted(System.Security.IPermission)'已过时:'IsGranted已过时,将在.NET Framework的未来版本中删除。请改为使用AppDomain或Assembly的PermissionSet属性。
(请注意,我正在使用VS2010在.Net 4.0上构建它。)
所以,看起来IsGranted已经过时了。我查看了AppDomain和Assembly的PermissionSet属性,并不清楚如何进行相同的检查。
对于LogEntry,看起来此信息并不重要,因此如果没有非托管权限,则不会将其视为严重故障。从同一角度考虑以下问题。也就是说,如果没有非托管代码权限,这不是一个大问题,我可以没有这些信息。
最后,有几个问题:
尝试保护对非托管代码的调用(例如P / Invoke)是个好主意吗?总是,永远,永远不会?
如果保护这些电话是个好主意,这样做是否合理?有更好的方法吗?
在.Net 4.0中进行等效检查的正确(即不过时)方法是什么?
答案 0 :(得分:8)
在.NET 4之前,代码访问安全性(CAS)是.NET Fx使用的安全模型。想法是根据证据确定代码可以做什么,并且不允许任何其他事情(SandBoxing)。例如,默认情况下,本地计算机上的代码可以完全信任(基本上它可以执行任何操作),而来自Internet的代码将具有受限制的权限(部分信任)方案。
IMO,如果您编写的代码不太可能在部分受信任的环境中运行,那么可能对此不太关心。但是对于部分受信任的程序集,