使用WCF服务的Windows身份验证不起作用-ORA-01017:无效的用户名/密码

使用WCF服务的Windows身份验证不起作用-ORA-01017:无效的用户名/密码

问题描述:

我有一个Silverlight应用程序,该应用程序从Windows服务下托管的WCF服务获取数据,该Windows服务在本地系统"帐户下运行,即NT AUTHORITY/SYSTEM.

我已使用以下App.config
在此WCF服务上启用Windows身份验证

I have a silverlight application which fetches data from a WCF Service hosted under a Windows Service which runs under the "Local System" account i.e. NT AUTHORITY/ SYSTEM.

I have enabled Windows Authentication on this WCF service using the below in my App.config

<system.servicemodel> 
<behaviors> 
  <endpointbehaviors> 
    <behavior name="webHttpBehavior"> 
      <webhttp /> 
    </behavior> 
  </endpointbehaviors> 
  <servicebehaviors> 
    <behavior name="defaultServiceBehavior"> 
      <servicemetadata httpgetenabled="true" /> 
      <servicedebug includeexceptiondetailinfaults="true" /> 
    </behavior> 
  </servicebehaviors> 
</behaviors> 
<bindings>            
  <basichttpbinding> 
    <binding name="winAuthBasicHttpBinding" opentimeout="05:00" sendtimeout="05:00"> 
      <security mode="TransportCredentialOnly"> 
        <transport clientcredentialtype="Windows" /> 
      </security> 
    </binding> 
  </basichttpbinding> 
</bindings> 
<servicehostingenvironment aspnetcompatibilityenabled="true" multiplesitebindingsenabled="true" /> 
<services> 
  <service behaviorconfiguration="defaultServiceBehavior" name="DataService.CrossDomainService"> 
    <endpoint address="" behaviorconfiguration="webHttpBehavior" binding="webHttpBinding" contract="DataService.ICrossDomainService"> 
      <identity> 
        <dns value="107.0.0.12" /> 
      </identity> 
    </endpoint> 
    <host> 
      <baseAddresses> 
        <add baseaddress="http://107.0.0.12:2035/" /> 
      </baseAddresses> 
    </host> 
  </service> 
  <service behaviorconfiguration="defaultServiceBehavior" name="DataService.NewDataService">         
    <endpoint address="" binding="basicHttpBinding" bindingconfiguration="winAuthBasicHttpBinding" contract="DataService.INewDataService"> 
      <identity> 
        <dns value="107.0.0.12" /> 
      </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    <host> 
      <baseAddresses> 
        <add baseaddress="http://107.0.0.12:2035/DataService/" /> 
      </baseAddresses> 
    </host> 
  </service> 
</services> 

</system.servicemodel>



我还使用Integrated Security = SSPI在Oracle的连接字符串中启用了Windows身份验证,如下所示:



I have also enabled Windows Authentication in the connection string for Oracle using Integrated Security=SSPI as below:

<connectionstrings>     
<add name="netTiersConnectionString" connectionstring="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=107.0.0.17)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=SVC001)));Integrated Security=SSPI; Min Pool Size= 1; Max Pool Size= 5;" /> 
</connectionstrings>    



现在,当Silverlight应用程序调用WCF服务时,将使用NT AUTHORITY/SYSTEM帐户而不是本身使用Windows身份验证的Silverlight应用程序中已登录用户的域名/用户名凭据来进行数据库连接.因此,我得到无效的用户名错误.

当我在控制台应用程序中托管WCF服务时,相同的配置可以正常工作.但是,当我托管Windows服务时,它在本地系统帐户下运行,因此我猜是这个问题.

我该怎么做才能使用登录用户的Windows身份验证凭据而不是本地系统帐户建立数据库连接?

谢谢,Pankaj Chamria



Now when the Silverlight app makes a call to the WCF Service, the database connection happens using NT AUTHORITY/SYSTEM account instead of domainname/username credentials of the logged in user in the Silverlight app which itself uses Windows Authentication. Hence I get the invalid username error.

The same configurations work fine when I host the WCF service in a console application. But when I host in a windows service, it runs under a Local System account and hence I guess this issue.

What can I do so that the database connection is made using windows authentication credentials of logged in user and not the Local System account?

Thanks, Pankaj Chamria

现在我不确定,但我相信用作登录oracle的帐户是运行服务的帐户,而不是用于运行该服务的帐户已致电服务.
您应该调查模仿行为
http://msdn.microsoft.com/en-us/library/ms730088.aspx [ ^ ]

因此,在您的WCF方法中执行以下操作(取自我链接的网站):
Now I''m not sure, but I beleave the account used as login to oracle is the one which runs the service not the one which has called the service.
You should look into impersonation
http://msdn.microsoft.com/en-us/library/ms730088.aspx[^]

So in you WCF method do something like the below (taken from the site I linked):
WindowsIdentity callerWindowsIdentity =         ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
    throw new InvalidOperationException("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
    //Do your thing here

}