1

我对 C# 还很陌生,所以请温柔:)

我想要完成的是创建一个应用程序,以便工作中的某个团队能够修改某些 DNS 条目。出于安全原因,我们无法让他们的 Active Directory 用户帐户修改对 DNS 的访问权限,并且我们正试图避免为他们更改 DNS 条目,因为这会占用我们大量的时间。

因此,我创建了一个具有多种获取和修改 DNS 条目的方法的 Windows 服务,以及一个使用 Windows 服务方法的 Windows 窗体。目的是让 Windows 服务在 Active Directory 用户帐户(服务帐户)下运行,该帐户具有对 DNS 的修改访问权限,并使 Windows 窗体在其正常用户帐户下运行。

如果我将表单作为我的管理员帐户(具有对 DNS 的修改访问权限)运行,一切正常,但是当我在我的普通用户帐户(没有对 DNS 的修改访问权限)下运行表单时,我得到了异常,

System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObjectSearcher.Initialize()
   at System.Management.ManagementObjectSearcher.Get()
   at ChangeDNS.ChangeDNSService.getCName(String cName) in C:\Tools\Projects\ChangeDNSService\ChangeDNSService\Program.cs:line 58

我无法找到参考资料或示例来阐明我所缺少的内容以及在表单和 Windows 服务之间传递凭据的正确方法是什么。您能否帮我指出正确的方向,我们将不胜感激。

谢谢并恭祝安康,

达里安

编辑:

表单具有以下代码,

ServiceReference1.ChangeDNSClient dnsClient = new ServiceReference1.ChangeDNSClient();
            dnsClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Console.WriteLine(dnsClient.getCName("TestDarianCName1"));

该服务具有以下代码,

public string getCName(string cName)
{
    serviceLog.Source = serviceName;
        string returnServer = "";

    try
        {
            ConnectionOptions connection = new ConnectionOptions();

        ManagementScope oMs = new ManagementScope("\\\\" + dnsServer + "\\root \\microsoftdns", connection);
                string strQuery = "select * from microsoftdns_" + recType + "Type where containername = '" + domain + "' and OwnerName = '" + cName + "." + domain + "'";
                ManagementObjectSearcher oS = new ManagementObjectSearcher(strQuery);
                oS.Scope = oMs;
                ManagementObjectCollection oRc = oS.Get();

        foreach (ManagementObject oR in oRc)
                {
                    returnServer = oR["RecordData"].ToString();
                }
        }
        catch (Exception e)
        {
            serviceLog.WriteEntry("Exception caught:\n\n" + e.ToString());
        }

    return returnServer;
}

它认为我在 ManagementObjectCollection oRc = oS.Get();

编辑2:

客户端绑定:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IChangeDNS" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8216/ServiceChangeDNS/service"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IChangeDNS"
                contract="ServiceReference1.IChangeDNS" name="WSHttpBinding_IChangeDNS">
                <identity>
                    <servicePrincipalName value="host/MyComputerName.domain.local" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

服务绑定:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ChangeDNSServiceBehavior" name="ChangeDNS.ChangeDNSService">
        <endpoint address="" binding="wsHttpBinding" contract="ChangeDNS.IChangeDNS" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8216/ServiceChangeDNS/service" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ChangeDNSServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
4

1 回答 1

0

看起来您正在客户端请求模拟。那么当然该服务将在用户上下文中运行,而不是在它自己的上下文中运行。您可以删除客户端上的模拟,如果您需要它来执行某些操作,那么只需为该呼叫执行它。

于 2013-10-24T17:55:29.533 回答