在Azure网站上,UserPrincipal.SetPassword会抛出UnauthorizedAccessException

时间:2015-09-17 15:47:34

标签: c# azure active-directory

我可以使用System.DirectoryServices.AccountManagement成功设置用户密码,使用:

using (var up = new UserPrincipal(principalContext))
{
   up.SetPassword(password);
}

但是,当我从Azure网站执行相同的代码时,它会抛出UnauthorizedAccessExceptionAccess is denied.。这是堆栈跟踪:

at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args) at System.DirectoryServices.AccountManagement.SDSUtils.SetPassword(DirectoryEntry de, String newPassword) at System.DirectoryServices.AccountManagement.ADStoreCtx.SetPassword(AuthenticablePrincipal p, String newPassword) at System.DirectoryServices.AccountManagement.PasswordInfo.SetPassword(String newPassword) at System.DirectoryServices.AccountManagement.AuthenticablePrincipal.SetPassword(String newPassword) at Cdp.ServiceBus.Adapters.ActiveDirectoryAdapter.CreateUser(String username, String password) in C:\agent\_work\a1b9797a\CDP\src\Cdp.ServiceBus.Adapters\ActiveDirectoryAdapter.cs:line 46

Active Directory实例正在Azure VM上运行。该网站连接到同一个虚拟网络。在本地开发时,我使用VPN连接到同一个虚拟网络。

使用ContextType.DomainContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing设置principalContext。我还指定虚拟网络的IP地址作为上下文的名称(主机)。此上下文的用户名和密码是AD VM中的管理员。

查看AD VM的安全日志,我可以看到,在本地开发时,会创建一个日志条目,因为我登录的管理员正在尝试重置密码。在Azure上时,不会创建此类日志条目。从这一点我想我可以得出结论,从来没有接到电话。没有其他日志条目向我提供它拥有的信息和/或无法处理它。

我最好的猜测是Azure不允许执行SetPassword API。这可以解释相当低级的UnauthorizedAccessException。你觉得怎么样?

编辑:

SDSUtils.SetPassword的签名是:

[SecurityCritical]
internal static void SetPassword(DirectoryEntry de, string newPassword)

是否允许Azure运行归因于SecurityCritical的代码?

1 个答案:

答案 0 :(得分:0)

我对此工作了一段时间,我想我已经明白了。为了使其工作,底层连接必须是安全的:

PrincipalContext _pc = new PrincipalContext(ContextType.Domain, "FQDN", null, ContextOptions.SecureSocketLayer | ContextOptions.Negotiate, _svsUser, _svsPwd);
UserPrincipal _up = UserPrincipal.FindByIdentity(_pc, IdentityType.SamAccountName, usernameToChange);
_up.SetPassword(newPassword);
_up.Save();

注意构造函数调用中的ConextOptions.SecureSocketLayer | ContextOptions.Negotiate。一旦我在DC上添加了这个并配置了SSL,它就开始工作了。