微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在.net中针对域控制器validation用户凭据

在.NET应用程序中,我试图通过用户名密码对Windows用户,本地用户以及域用户进行身份validation。 我已经试过这个解决scheme 。 我的代码获取PrincipalContext看起来如下:

protected static PrincipalContext TryCreatePrincipalContext(String domain) { var computerDomain = TryGetComputerDomain(); if (String.IsNullOrEmpty(domain) && String.IsNullOrEmpty(computerDomain)) return new PrincipalContext(ContextType.Machine); else if (String.IsNullOrEmpty(domain)) return new PrincipalContext(ContextType.Domain,computerDomain); else return new PrincipalContext(ContextType.Domain,domain); } protected static String TryGetComputerDomain() { try { var domain = Domain.GetComputerDomain(); return domain.Name; } catch { return null; } }

这对于本地Windows用户以及ActiveDirectory中的远程用户都可以正常工作。 但是,如果我尝试在一台机器上运行身份validation,那么它会连接到一个非ActiveDirectory Domain Master,例如。 一个Samba服务器我得到以下exception:

System.DirectoryServices.AccountManagement.PrincipalServerDownException: Mit dem Server konnte keine Verbindung hergestellt werden. ---> System.DirectoryServices.Protocols.LdapException: Der LDAP-Server ist nicht verfügbar. bei System.DirectoryServices.Protocols.LdapConnection.Connect() bei System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(DirectoryRequest request,Int32& messageID) bei System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request,TimeSpan requestTimeout) bei System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request) bei System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName,ServerProperties& properties) --- Ende der internen Ausnahmestapelüberwachung --- bei System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName,ServerProperties& properties) bei System.DirectoryServices.AccountManagement.PrincipalContext.DoServerVerifyAndPropRetrieval() bei System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType,String name,String container,ContextOptions options,String userName,String password) bei System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType,String name) bei DomainAuthTest.DomainAuthenticator.TryCreatePrincipalContext(String domain) bei DomainAuthTest.DomainAuthenticator.Authenticate(String domainUser,String password) bei DomainAuthTest.Program.Main(String[] args)

所以似乎PrincipalContext在ContextType.Domain的情况下尝试使用LDAP。 如果我尝试使用ContextType.Machine,则不能使用工作组/域名,因为PrincipalContext尝试直接连接到机器。 如果在同一台机器上已经有与该机器的连接,那么这将失败。

所以我的问题是:

.Net核心命令行应用程序| Process.Start()在一些机器上运行,但不在其他机器上运行

如何从C#桌面应用程序以全屏模式打开认浏览器?

自动打开谷歌浏览器,单击button,并closures铬C#WinForms

并发性IO操作问题

语言栏在c#.NET中改变语言

如何使用凭据域,用户名密码对域主服务器进行身份validation,该服务器不一定基于ActiveDirectory?

是否有托pipeAPI来完成上述任务?

如果没有pipe理的基础class,那么这样做的正确方向是什么?

谢谢您的回复

什么USB设备(友好名称)当前连接到PC?

为什么MS不能使用.Net打开?

在.NET 4.5中编写的软件需要什么版本的.NET运行时?

进程的当前目录是否与其工作目录相同?

如何在.NET中确定我的Monitor的真实像素大小?

为了完整性,这里我的解决方案似乎正是我想要的:

public class WinApiDomainAuthenticator { [DllImport("advapi32.dll",SetLastError = true)] public static extern bool logonUser(string lpszUsername,string lpszDomain,string lpszPassword,int dwlogonType,int dwlogonProvider,out IntPtr phToken); [DllImport("kernel32.dll",CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); public static IPrincipal Authenticate(String domainUser,String password) { var userToken = IntPtr.Zero; var creds = new DomainAuthCredentials(domainUser,password); if (! logonUser(creds.Username,creds.Domain,creds.Password,(int)logonType.logoN32_logoN_BATCH,(int)logonProvider.logoN32_PROVIDER_DEFAULT,out userToken)) { var error = new Win32Exception(Marshal.GetLastWin32Error()); throw new SecurityException("Error while authenticating user",error); } var identity = new WindowsIdentity(userToken); if (userToken != IntPtr.Zero) CloseHandle(userToken); return ConvertwindowsIdentityToGenericPrincipal(identity); } protected static IPrincipal ConvertwindowsIdentityToGenericPrincipal(WindowsIdentity windowsIdentity) { if (windowsIdentity == null) return null; // Identity in format DOMAINUsername var identity = new GenericIdentity(windowsIdentity.Name); var groupNames = new string[0]; if (windowsIdentity.Groups != null) { // Array of Group-Names in format DOMAINGroup groupNames = windowsIdentity.Groups .Select(gId => gId.Translate(typeof(NTAccount))) .Select(gNt => gNt.ToString()) .ToArray(); } var genericPrincipal = new GenericPrincipal(identity,groupNames); return genericPrincipal; } protected class DomainAuthCredentials { public DomainAuthCredentials(String domainUser,String password) { Username = domainUser; Password = password; Domain = "."; if (!domainUser.Contains(@"")) return; var tokens = domainUser.Split(new char[] { '\' },2); Domain = tokens[0]; Username = tokens[1]; } public DomainAuthCredentials() { Domain = String.Empty; } #region Properties public String Domain { get; set; } public String Username { get; set; } public String Password { get; set; } #endregion } }

logonType和logonProvider枚举反映了“Winbase.h”中的定义。 我解决logonType.logoN32_logoN_BATCH而不是logonType.logoN32_logoN_NETWORK,因为桑巴3.4.X似乎有这种类型的麻烦。

这是我刚刚为我自己开发的应用程序所做的一个 – 需要Framework v3.5或更高版本….

public static bool Authenticate(string user,string password) { // Split the user name in case a domain name was specified as DOMAINUSER string[] NamesArray = user.Split(new char[] { '\' },2); // Default vars for names & principal context type string DomainName = string.Empty; string UserName = string.Empty; ContextType TypeValue = ContextType.Domain; // Domain name was supplied if (NamesArray.Length > 1) { DomainName = NamesArray[0]; UserName = NamesArray[1]; } else { // Pull domain name from environment DomainName = Environment.UserDomainName; UserName = user; // Check this against the machine name to pick up on a workgroup if (string.Compare(DomainName,System.Environment.MachineName,StringComparison.InvariantCultureIgnoreCase) == 0) { // Use the domain name as machine name (local user) TypeValue = ContextType.Machine; } } // Create the temp context using (PrincipalContext ContextObject = new PrincipalContext(TypeValue,DomainName)) { // Validate the credentials return ContextObject.ValidateCredentials(UserName,password); } }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐