出现一个操作错误 (An operations error occurred)

 问题描述:

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 出现一个操作错误  An operations error occurred

--> System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred.

 

Server stack trace:
  at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
  at System.DirectoryServices.DirectorySearcher.FindAll()

 

问题原因:

在访问(Active Directory)活动目录时的安全性有关。

详见:http://support.microsoft.com/kb/329986/zh-cn

通常在不进行角色模拟的情况下,访问本地(localAD是没有问题的;但是如果访问服务器的AD时,就会出现“出现一个操作错误”。用角色模拟就可以解决。

 

解决方案一:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

public class IdentityImpersonation

    {

        /// <summary>

        /// Logons the user.

        /// </summary>

        /// <param name="lpszUsername">The LPSZ username.</param>

        /// <param name="lpszDomain">The LPSZ domain.</param>

        /// <param name="lpszPassword">The LPSZ password.</param>

        /// <param name="dwLogonType">Type of the dw logon.</param>

        /// <param name="dwLogonProvider">The dw logon provider.</param>

        /// <param name="phToken">The ph token.</param>

        /// <returns></returns>

        [DllImport("advapi32.dll", SetLastError = true)]

        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

 

        /// <summary>

        /// Duplicates the token.

        /// </summary>

        /// <param name="ExistingTokenHandle">The existing token handle.</param>

        /// <param name="SECURITY_IMPERSONATION_LEVEL">The SECURIT y_ IMPERSONATIO n_ LEVEL.</param>

        /// <param name="DuplicateTokenHandle">The duplicate token handle.</param>

        /// <returns></returns>

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

 

        /// <summary>

        /// Closes the handle.

        /// </summary>

        /// <param name="handle">The handle.</param>

        /// <returns></returns>

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        public extern static bool CloseHandle(IntPtr handle);

 

        // 要模拟的用户的用户名、密码、域(机器名)

        private String _sImperUsername;

        private String _sImperPassword;

        private String _sImperDomain;

 

        //记录模拟上下文

        private WindowsImpersonationContext _imperContext;

        private IntPtr _adminToken;

        private IntPtr _dupeToken;

 

        // 是否已停止模拟

        private Boolean _bClosed;

 

        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="impersonationUsername">所要模拟的用户的用户名</param>

        /// <param name="impersonationPassword">所要模拟的用户的密码</param>

        /// <param name="impersonationDomain">所要模拟的用户所在的域</param>

        public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain)

        {

            _sImperUsername = impersonationUsername;

            _sImperPassword = impersonationPassword;

            _sImperDomain = impersonationDomain;

            _adminToken = IntPtr.Zero;

            _dupeToken = IntPtr.Zero;

            _bClosed = true;

        }

 

        /// <summary>

        /// 析构函数

        /// </summary>

        ~IdentityImpersonation()

        {

            if (!_bClosed)

            {

                StopImpersonate();

            }

        }

 

        /// <summary>

        /// 开始身份角色模拟。

        /// </summary>

        /// <returns></returns>

        public Boolean BeginImpersonate()

        {

            Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);

            if (!bLogined)

            {

                return false;

            }

 

            Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);

            if (!bDuped)

            {

                return false;

            }

 

            WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);

            _imperContext = fakeId.Impersonate();

            _bClosed = false;

 

            return true;

        }

 

        /// <summary>

        /// 停止身分角色模拟。

        /// </summary>

        public void StopImpersonate()

        {

            //_imperContext.Undo();

 

            CloseHandle(_dupeToken);

            CloseHandle(_adminToken);

            _bClosed = true;

        }

 

    }

 

但是用这种方法模拟时要注意:

public static IdentityImpersonation impersonate = new IdentityImpersonation(ADUser, ADPassword, ADDomain);

在模拟时,账户格式:domain\loginname.

  <appSettings>

    <!-- ADPath的格式,必须严格按照下面的格式 -->

    <add key="ADPath" value="LDAP://OU=ou,DC=domain,DC=com"/>

    <add key="ADAdminUser" value="domain\administrator"/>

    <add key="ADPassword" value="123-aaa"/>

    <add key="ADDomain" value="domain.com"/>

    <!-- ImageUrl -->

  </appSettings>

 

如果账户不对或LDAP有误,将会出项“没有注册类别”的错误

 

解决方案二:

using System.Web.Hosting;
...
...

// Code here runs as the logged on user

using (HostingEnvironment.Impersonate()) {
// This code runs as the application pool user
     DirectorySearcher searcher ...
}

// Code here runs as logged on user again

但是,这种方法也存在不足,

详见:http://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.impersonate.aspx

 

Name

Description

Impersonate()

Impersonates the user represented by the application identity.

Impersonate(IntPtr)

Impersonates the user represented by the specified user token.

Impersonate(IntPtr, String)

Impersonates the user specified by the configuration settings for the specified virtual path, or the specified user token.

 

解决方案三:

           using (DirectoryEntry entry = new DirectoryEntry(strPath, ADUser, ADPassword, AuthenticationTypes.Secure))

            {

                using (System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry))

                {

                    // code here

                }

            }

直接用域用户的帐号来获得entry

转载于:https://www.cnblogs.com/LeimOO/archive/2009/01/17/1377485.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值