无法调用函数,未命中断点,- 无法从 mscorlib 加载程序集
Function cannot be called, no breakpoint hit, - could not load assembly from mscorlib
问题
我有一个方法,可以调用但永远不会执行。
调用 'CreateHomeDrive' 的行如下所示:
FileInterface.HomeDriveCreation.CreateHomeDrive("my_domain","admin_user","admin_pwd", document.UserName);
成功到达该行,相应的中断指针停止
应该到达但从未到达以下 Break 指针。
只有 1 个方法引用此函数:
public class HomeDriveCreation
{
public static void CreateHomeDrive(string domainName, string adminUser, string adminPassword, string userNameToCreate)
{
{/*Break pint here is never reached!*/ }
// method logic here...
}
}
知道为什么永远无法达到此代码吗?中断指针位于函数的第一行,因此根据我的理解,应该始终到达此中断标记。
确实抛出了一个错误,这对我没有帮助:
One or more errors occurred.
(Could not load type 'System.Security.Principal.WindowsImpersonationContext'
from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=/*private?*/'.)
项目结构
项目结构如下所示:
FileInterface 是一个 .net Framework class 库,
调用 FileInterface.HomeDriveCreation 的 JiraBackgroundTasks 是一个 .net core 3.5 class 库。
添加了对 System.Security 的引用
具体class应该叫什么
要调用的代码源自 Microsoft 模拟参考 https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.impersonate?redirectedfrom=MSDN&view=netframework-4.8#System_Security_Principal_WindowsIdentity_Impersonate_System_IntPtr_
这是完整的 class:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.IO;
using System.Security.AccessControl;
namespace FileInterface
{
public class HomeDriveCreation
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public static void CreateHomeDrive(string domainName, string adminUser, string adminPassword, string userNameToCreate)
{
{ }
SafeTokenHandle safeTokenHandle;
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(adminUser, domainName, adminPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
// Use the token handle returned by LogonUser.
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
{
string path = $@"\server\Data\Home\{userNameToCreate}";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.ReadAndExecute, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.Write, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.DeleteSubdirectoriesAndFiles, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.FullControl, AccessControlType.Allow);
}
}
// Releasing the context object stops the impersonation
// Check the identity.
}
}
// Adds an ACL entry on the specified directory for the specified account.
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
}
WindowsImpersonationContext 特定于 .Net Framework。
请注意您发布的文章中的“适用于”部分。
对于 .Net Core,您可以使用 WindowsIdentity.RunImpersonated .
另见 SO: WindowsImpersonationContext & Impersonate() not found in ASP.Core
这种情况下的问题是模拟在 .net core 中的处理方式不同
尽管该项目是 .net 框架,Visual Studio 无法满足多框架目标解决方案的要求。
有关如何在 .net 核心中模拟的更多信息,请参见此处:
https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=net-5.0
至于模拟文件夹访问权限的具体任务,在这里找到了很好的答案:
How to provide user name and password when connecting to a network share(来自 Luke Quinane 的回答)
请记住,当网络位置映射到 Windows 中的不同用户时,这将不起作用。在这种情况下,程序将在内部映射网络驱动器并在使用后对其进行处理。
实施他的 class 然后像这样使用它:
using (new NetworkConnection(@"\server\Data\Home", cred))
{
string path = $@"\server\Data\Home\testuserfolder";
string domainName = "domain.com";
string userNameToCreate = "testuser";
Directory.CreateDirectory(path);
SetFullPermission(path, userNameToCreate);
}
问题
我有一个方法,可以调用但永远不会执行。
调用 'CreateHomeDrive' 的行如下所示:
FileInterface.HomeDriveCreation.CreateHomeDrive("my_domain","admin_user","admin_pwd", document.UserName);
成功到达该行,相应的中断指针停止
应该到达但从未到达以下 Break 指针。
只有 1 个方法引用此函数:
public class HomeDriveCreation
{
public static void CreateHomeDrive(string domainName, string adminUser, string adminPassword, string userNameToCreate)
{
{/*Break pint here is never reached!*/ }
// method logic here...
}
}
知道为什么永远无法达到此代码吗?中断指针位于函数的第一行,因此根据我的理解,应该始终到达此中断标记。
确实抛出了一个错误,这对我没有帮助:
One or more errors occurred.
(Could not load type 'System.Security.Principal.WindowsImpersonationContext'
from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=/*private?*/'.)
项目结构
项目结构如下所示:
FileInterface 是一个 .net Framework class 库,
调用 FileInterface.HomeDriveCreation 的 JiraBackgroundTasks 是一个 .net core 3.5 class 库。
添加了对 System.Security 的引用
具体class应该叫什么
要调用的代码源自 Microsoft 模拟参考 https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.impersonate?redirectedfrom=MSDN&view=netframework-4.8#System_Security_Principal_WindowsIdentity_Impersonate_System_IntPtr_ 这是完整的 class:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.IO;
using System.Security.AccessControl;
namespace FileInterface
{
public class HomeDriveCreation
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public static void CreateHomeDrive(string domainName, string adminUser, string adminPassword, string userNameToCreate)
{
{ }
SafeTokenHandle safeTokenHandle;
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(adminUser, domainName, adminPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
// Use the token handle returned by LogonUser.
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
{
string path = $@"\server\Data\Home\{userNameToCreate}";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.ReadAndExecute, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.Write, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.DeleteSubdirectoriesAndFiles, AccessControlType.Allow);
AddDirectorySecurity(path, $@"{domainName}\{userNameToCreate}", FileSystemRights.FullControl, AccessControlType.Allow);
}
}
// Releasing the context object stops the impersonation
// Check the identity.
}
}
// Adds an ACL entry on the specified directory for the specified account.
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
}
WindowsImpersonationContext 特定于 .Net Framework。 请注意您发布的文章中的“适用于”部分。
对于 .Net Core,您可以使用 WindowsIdentity.RunImpersonated .
另见 SO: WindowsImpersonationContext & Impersonate() not found in ASP.Core
这种情况下的问题是模拟在 .net core 中的处理方式不同
尽管该项目是 .net 框架,Visual Studio 无法满足多框架目标解决方案的要求。
有关如何在 .net 核心中模拟的更多信息,请参见此处: https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.runimpersonated?view=net-5.0
至于模拟文件夹访问权限的具体任务,在这里找到了很好的答案: How to provide user name and password when connecting to a network share(来自 Luke Quinane 的回答)
请记住,当网络位置映射到 Windows 中的不同用户时,这将不起作用。在这种情况下,程序将在内部映射网络驱动器并在使用后对其进行处理。
实施他的 class 然后像这样使用它:
using (new NetworkConnection(@"\server\Data\Home", cred))
{
string path = $@"\server\Data\Home\testuserfolder";
string domainName = "domain.com";
string userNameToCreate = "testuser";
Directory.CreateDirectory(path);
SetFullPermission(path, userNameToCreate);
}