在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一早在浏览代码时看到如下代码(我想这段代码的来源是kb306158),这段代码的作用是,当一个通过Active Directory账号登陆系统的用户,需要上传、创建目录、下载时,需要先校验该用户是否具有目录操作权限, 代码如下: public const int LOGON32_LOGON_INTERACTIVE = 2; public const int LOGON32_PROVIDER_DEFAULT = 0; private string _logOnUsername; private string _logOnDomain; private string _logOnPassword; WindowsImpersonationContext impersonationContext; // to check whether the acct info input is a logoned one, // if past the validation, output a token [DllImport("advapi32.dll", CharSet = CharSet.Auto)] public static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); // create a new token derived from the input token [DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)] public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); // to impersonate private bool impersonateValidUser(String userName, String domain, String password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; // validate whether logoned on with the supplied parameters if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { // SecurityImpersonation // The server can impersonate the client's security context on the local system. if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) return true; else return false; } else return false; } else return false; } private void undoImpersonation() { impersonationContext.Undo(); } // the parameters' value are all kept in web.config, // it's a fixed account, not current logined user's acct. public FileAccess(string logonDomain, string logonUsername, string logonPassword) { _logOnDomain = logonDomain; _logOnUsername = logonUsername; _logOnPassword = logonPassword; } public bool FileExists(string filePathName) { if (impersonateValidUser(_logOnUsername, _logOnDomain, _logOnPassword)) { try { if (File.Exists(filePathName)) { return true; } else { return false; } } finally { undoImpersonation(); } } else { throw (new Exception("Failed in impersonation.")); } }
Q: 为什么需要DuplicateToken > SecurityImpersonation The server can impersonate the client's security context on the local system. > SecurityDelegation The server can impersonate the client's security context on remote systems. At the SecurityImpersonation level, most of the thread's actions occur in the security context of the thread's impersonation token rather than in the primary token of the process that owns the thread. For example, if an impersonating thread opens a securable object, the system uses the impersonation token to check the thread's access. Similarly, if an impersonating thread creates a new object, for example by calling the CreateFile function, the owner of the new object is the default owner from the client's access token. Q: 这个被模拟的用户(即此处的FileAccess中传入的帐号信息)的权限应该设置为什么? > 为 ASPNET 帐户授予“作为操作系统的一部分”权限。(注意:我们不建议使用这种方法解决此问题。) > 在 Machine.config 文件的 <processModel> 配置节中,将运行 Aspnet_wp.exe 进程所使用的帐户更改为 System 帐户。 在此贴中,这位大牛提出了这个问题,他认为无论是使用LogonUser还是使用System.DiretoryServices都是不完美的,有漏洞的。比如LogonUser必须会提供一个有SE_CHANGE_NOTIFY_NAME权限的账号,这个比较麻烦,使用DirectoryServices则需要查看AD属性,并认为这种方式会在客户端留下AD scheme的缓存,代价太大不划算,且GetLastError捕捉的异常也并不能100%定位是否是用户校验未通过,见下面这段代码。 // create a "principal context" - e.g. your domain (could be machine, too) using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN")) { // validate the credentials bool isValid = pc.ValidateCredentials("myuser", "mypassword") } 还可以进行一些延伸阅读 See also:
我觉得到了这一步,我已经对windows/AD登陆用户的校验大致有了一点了解。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论