- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
已经asked , 和 answered for .NET ,但现在是时候获得 native Win32 代码的答案了:
我如何验证 Windows 用户名和密码?
我asked this question before for managed code .现在是 native 解决方案的时候了。
需要指出一些更常提出的解决方案的陷阱:
很多人suggest querying the Active Directory为了某件事。如果抛出异常,则您知道凭据无效 - 正如 this stackoverflow question 中所建议的那样.
有some serious drawbacks to this approach然而:
You are not only authenticating a domain account, but you are also doing an implicit authorization check. That is, you are reading properties from the AD using an impersonation token. What if the otherwise valid account has no rights to read from the AD? By default all users have read access, but domain policies can be set to disable access permissions for restricted accounts (and or groups).
Binding against the AD has a serious overhead, the AD schema cache has to be loaded at the client (ADSI cache in the ADSI provider used by DirectoryServices). This is both network, and AD server, resource consuming - and is too expensive for a simple operation like authenticating a user account.
You're relying on an exception failure for a non-exceptional case, and assuming that means invalid username and password. Other problems (e.g. network failure, AD connectivity failure, memory allocation error, etc) are then mis-intrepreted as authentication failure.
使用DirectoryEntry
class is .NET 是验证凭据的不正确方法的示例:
无效方法 1a - .NET
DirectoryEntry entry = new DirectoryEntry("persuis", "iboyd", "Tr0ub4dor&3");
object nativeObject = entry.NativeObject;
无效方法 1b - .NET #2
public static Boolean CheckADUserCredentials(String accountName, String password, String domain)
{
Boolean result;
using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, accountName, password))
{
using (DirectorySearcher searcher = new DirectorySearcher(entry))
{
String filter = String.Format("(&(objectCategory=user)(sAMAccountName={0}))", accountName);
searcher.Filter = filter;
try
{
SearchResult adsSearchResult = searcher.FindOne();
result = true;
}
catch (DirectoryServicesCOMException ex)
{
const int SEC_E_LOGON_DENIED = -2146893044; //0x8009030C;
if (ex.ExtendedError == SEC_E_LOGON_DENIED)
{
// Failed to authenticate.
result = false;
}
else
{
throw;
}
}
}
}
以及通过 ADO 连接查询 Active Directory:
无效方法 1c - native 查询
connectionString = "Provider=ADsDSOObject;
User ID=iboyd;Password=Tr0ub4dor&3;
Encrypt Password=True;Mode=Read;
Bind Flags=0;ADSI Flag=-2147483648';"
SELECT userAccountControl
FROM 'LDAP://persuis/DC=stackoverflow,DC=com'
WHERE objectClass='user' and sAMAccountName = 'iboyd'
即使您的凭据有效,但您无权查看您的目录条目,这两种方法都会失败:
Others建议使用 LogonUser() API函数。这听起来不错,但不幸的是,调用用户有时需要通常只授予操作系统本身的权限:
The process calling LogonUser requires the SE_TCB_NAME privilege. If the calling process does not have this privilege, LogonUser fails and GetLastError returns ERROR_PRIVILEGE_NOT_HELD.
In some cases, the process that calls LogonUser must also have the SE_CHANGE_NOTIFY_NAME privilege enabled; otherwise, LogonUser fails and GetLastError returns ERROR_ACCESS_DENIED. This privilege is not required for the local system account or accounts that are members of the administrators group. By default, SE_CHANGE_NOTIFY_NAME is enabled for all users, but some administrators may disable it for everyone.
分发“作为操作系统的一部分”特权不是您愿意随意做的事情 - 正如 Microsoft 在 knowledge base article 中指出的那样:
...the process that is calling LogonUser must have the SE_TCB_NAME privilege (in User Manager, this is the "Act as part of the Operating System" right). The SE_TCB_NAME privilege is very powerful and should not be granted to any arbitrary user just so that they can run an application that needs to validate credentials.
此外,如果指定了空白密码,对 LogonUser() 的调用将失败。
PrincipalContext
有一种验证方法,仅在 .NET 3.5 和更新版本中可用,允许用户在不执行授权检查的情况下进行身份验证:
// create a "principal context" - e.g. your domain (could be machine, too)
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "stackoverflow.com"))
{
// validate the credentials
bool isValid = pc.ValidateCredentials("iboyd", "Tr0ub4dor&3")
}
不幸的是,此代码仅在 .NET 3.5 及更高版本中可用。
是时候找到原生的等价物了。
最佳答案
Here is Microsoft's recommendation .
至于其他答案,我不太确定您为什么要将它们击落。您在尝试验证凭据时提示(相对边缘情况)失败,但如果您实际上要对这些凭据执行某些操作,那么该操作无论如何都会失败。如果您实际上不打算使用这些凭据执行某些操作,那么为什么首先需要验证它们?这看起来有点人为的情况,但显然我不知道你想要完成什么。
关于windows - Win32 : How to validate credentials against Active Directory?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7111618/
我正在使用 git-credential-store与我的存储库。但是我注意到当我运行 git push 它启动git-credential-cache--daemon 并且在我关闭终端之前不会关闭它
这些是我正在使用的导入: import com.novell.ldap.*; import java.io.UnsupportedEncodingException; 我正在尝试进行一个非常简单的密码
我的 hdp 集群配置了带有 AD 的 kerberos。所有 HDP 服务帐户都生成了主体和 key 表,包括 spark。 我知道服务帐户没有密码并设置为未过期。现在在执行 kinit -kt s
服务器不能只是将临时凭证“升级”为 token 凭证并保留相同的 key 和 secret 吗? 然后,客户端可以在收到来自服务器的说明临时凭据已“升级”的回调后立即开始进行经过身份验证的调用。 当然
Apache Camel 与 AWS S3 接口(interface)良好,但我发现它没有正确构建的场景。回顾我在网上看到的所有 Camel 示例,我从未见过有人在非本地环境中使用推荐的行业标准 AW
大家好,我遇到了一个问题,这是我第一次为支付门户设置 Mutial SSL,下面的代码是我正在使用的代码,我得到的错误是: System.Web.Services.Protocols.SoapExce
我创建了一个 server.keystore,然后是一个 client.keyStore 和一个 client.crt,我用它来做 client.truststore 别名为 devmyserverk
我正在尝试从 AngularJS 页面连接到 ASP.NET Web-API Web 服务,我得到以下信息 Credentials 标志为“true”,但“Access-Control-Allow-C
Windows 更新后,出现保存凭据问题,rdp 总是询问密码,无法保存。原因是 Windows Defender Credential Guard。如何解决这个问题? 最佳答案 我的解决方案在这里,
我正在使用 react-native-facebook-login 包来登录用户。目前流程运行良好,在用户输入他们的详细信息后,我成功地看到了一个带有他们信息的对象。 当我尝试使用 signInWit
在使用 Sourcetree 时,我不断收到错误 git: 'credential-oskeychain' is not a git command. See 'git --help'. 我很确定应该
“根账户凭证”和“IAM 用户凭证”之间有什么区别? 还有一个问题: 根据描述,建议使用“IAM 用户凭据”,但无法使用“IAM 用户凭据”在 S3 中访问 你能解释一下这是为什么吗? 最佳答案 您的
Spring 3.1Tomcat 6.* 我正在制作一个 Spring 3.1 webapp,使用 LDAP 进行身份验证。 我用我编写的 JNDI 风格的 Java 程序(引述如下)测试了 LDAP
Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenti
我正在使用 firebase Admin SDK,但我在运行时收到此错误: Error:(22, 36) java: cannot access com.google.auth.Credentials
vscode 1.45.1版本使用克隆存储库时,我收到“Bad credentials”。最近我在github上换了用户名。可能就是这个原因。我如何告诉vs code?
我已经为 Classroom API 实现了 Java QuickStart,但在运行时收到错误消息“java.io.FileNotFoundException:未找到资源:/credentials.
我正在使用 Jenkins 主/从设置。我希望 Jenkins 有一个凭证信息“来源”。不是散落在各处的 key /密码。 因此,我不想在 Jenkins 中定义我的 SCM(使用来自 Jenkins
使用azure aks get-credentials --admin可以获取kubernetes管理配置文件,azure aks get-credentials只能获取azure上的用户配置文件。
使用azure aks get-credentials --admin可以获取kubernetes管理配置文件,azure aks get-credentials只能获取azure上的用户配置文件。
我是一名优秀的程序员,十分优秀!