System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity 的奇怪问题
我们正在编写一个系统,允许用户通过 Intranet 上的 Web 应用程序更改其帐户密码。
起初,一切似乎都进展顺利。在开发过程中,我们的测试帐户的密码可以毫无问题地更改。
然而,当我们让系统上线时,我们开始遇到问题。症状如下:
- 起初,一切都很好。用户 可以更改他们的密码。
- 在一些 点,出现以下错误 UserPrincipal.FindByIdentity: “System.Runtime.InteropServices.COMException: 认证机制是 未知。 “
- 从那时起,就努力 通过网络更改密码 应用程序导致错误: “System.Runtime.InteropServices.COMException: 服务器无法运行。 “
- 如果我手动回收应用程序池, 一切似乎都会自行修复,直到 更多错误开始发生......即, 该过程再次开始于 第 1 阶段。
这是相关的代码片段:
private static PrincipalContext CreateManagementContext() {
return new PrincipalContext(
ContextType.Domain,
ActiveDirectoryDomain,
ActiveDirectoryManagementAccountName,
ActiveDirectoryManagementAccountPassword);
}
private static void ChangeActiveDirectoryPasword(string username, string password) {
if (username == null) throw new ArgumentNullException("username");
if (password == null) throw new ArgumentNullException("password");
using (var context = CreateManagementContext())
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username)) {
user.SetPassword(password);
}
}
有任何线索说明为什么会发生这种情况吗? Google 搜索并没有找到任何真正有用的东西,MSDN 上的文档也没有。
We're writing a system that allows a user to change their account password through a web application on our intranet.
At first, everything appeared to be running smoothly. During development passwords for our test accounts could be changed with no problem.
When we made the system live, however, we started running into issues. Here are the symptoms:
- At first, everything is fine. Users
can change their passwords. - At some
point, the following error occurs in
UserPrincipal.FindByIdentity:
"System.Runtime.InteropServices.COMException:
The authentication mechanism is
unknown. " - From then on, trying to
change a password through the web
application results in the error:
"System.Runtime.InteropServices.COMException:
The server is not operational. " - If I manually recycle the app pool,
everything seems to fix itself until
more errors begin happening... i.e.,
the process starts all over again at
phase 1.
Here's the relevant snippet of code:
private static PrincipalContext CreateManagementContext() {
return new PrincipalContext(
ContextType.Domain,
ActiveDirectoryDomain,
ActiveDirectoryManagementAccountName,
ActiveDirectoryManagementAccountPassword);
}
private static void ChangeActiveDirectoryPasword(string username, string password) {
if (username == null) throw new ArgumentNullException("username");
if (password == null) throw new ArgumentNullException("password");
using (var context = CreateManagementContext())
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username)) {
user.SetPassword(password);
}
}
Any clues as to why this is happening? Google searches aren't turning up anything really helpful, and neither are the docs on MSDN.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我注意到的第一件事是您正在使用继承的 UserPrincipal.FindByIdentity来自 AuthenticablePrincipal 继承自 校长。我之所以这么说是因为
Principal
类在FindByIdentity
中存在已知的内存泄漏。如果您查看此 MSDN 条目,您会注意到底部,来自 Microsoft 的 Gary Caldwell 说了以下内容:我猜这是你的问题。内存泄漏导致应用程序池被填满并最终导致错误,直到应用程序池被重置并释放内存。
当我们使用任何活动目录功能时,我们使用以下方法来完成用户密码的设置:
此外,如果您希望用户直接更改密码并且您不想依赖他们的诚实,您可能需要考虑使用 LDAP 的
ChangePassword
功能,如下所示:这会强制用户在更改为新密码之前知道之前的密码。
我希望这有帮助,
谢谢!
First thing I notice is that you are using UserPrincipal.FindByIdentity which is inherited from AuthenticablePrincipal which is inherited from Principal. I say all this because the
Principal
class has a known memory leak in theFindByIdentity
. If you have a look at this MSDN entry, you will notice at the bottom that Gary Caldwell from Microsoft said the following:I would guess that this is your issue. The memory leak causes the Application Pool to fill up and finally cause errors, until the Application Pool is reset and the memory is disposed.
When we use any active directory functions, we use the following to accomplish setting of the user's password:
Also, if you're wanting the users to change the passwords directly and you don't want to rely on their honesty, you might want to consider using the
ChangePassword
function of LDAP like this:This forces the user to know the prior password before changing to the new one.
I hope this helps,
Thanks!