Проблема аутентификации / олицетворения при вызове ASP.NET к службе WCF - PullRequest
1 голос
/ 03 ноября 2010

У меня есть веб-страница, которая вызывает службу WCF, которая выполняет вызов базы данных sql с использованием встроенной безопасности. Я получаю сообщение об ошибке «Ошибка входа пользователя« CorpDomain \ ServerName01 $ »». Я хочу, чтобы все слои выполнялись под учетными данными AD пользователя (работающими в интрасети), а именно: «CorpDomain \ Albert».

На сервере (Win 2008 / IIS 7) у меня включена проверка подлинности Windows и все остальное (включая анонимный) в разделе «Проверка подлинности» как для веб-клиента, так и для службы WCF.

Вот мой клиент web.config:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0"/>
        <authentication mode="Windows"/>
        <identity impersonate="true"/>
        <customErrors mode="Off"/>
    </system.web>
    <system.serviceModel>
   <bindings>
     <netTcpBinding>
       <binding name="NetTcpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
         <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
         <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
         <!--<security mode="Transport">
           <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
           <message clientCredentialType="Windows" />
         </security>-->
      </binding>
    </netTcpBinding>
  </bindings>
  <client>
   <endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
    contract="MySvc.IMyService" name="NetTcpBinding_IMyService" />
  </client>
  <behaviors>
    <endpointBehaviors>
      <behavior name="ClientUserNameBehavior">
        <clientCredentials>
          <windows allowedImpersonationLevel="Impersonation"/>
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

Вот мой сервис WCF web.config:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <authentication mode="Windows"/>
    <identity impersonate="true"/>
  </system.web>
  <connectionStrings>
    <!--DB CONNECTION-->
    <add name="myDB" connectionString="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Carbon;Data Source=mydbname,10600" providerName="System.Data.SqlClient"/>
  </connectionStrings>

  <system.serviceModel>
    <services>
      <service name="WCFServices.MyService" behaviorConfiguration="MyServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8000/WCFServices/MyService"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding" contract="WCFServices.IMyService" bindingConfiguration="tcpWindowsSecurity" bindingNamespace="http://WCFServices.MySvc/"/>
        <endpoint address="MEX" binding="mexTcpBinding" contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceMetadata httpGetEnabled="false"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceAuthorization impersonateCallerForAllOperations="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="tcpWindowsSecurity" maxReceivedMessageSize="524288" maxBufferSize="524288">
          <!--<security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Windows" protectionLevel="None" />
          </security>-->
        </binding>
      </netTcpBinding>
    </bindings>

    <!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true" >-->
    <serviceHostingEnvironment >
      <serviceActivations>
        <add relativeAddress="~/MyService.svc" service="WCFServices.MyService"/>
      </serviceActivations>
    </serviceHostingEnvironment>

  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

на стороне клиента :

Request.ServerVariables ["AUTH_USER"]. ToString () = "CorpDomain \ Albert"

Page.User.Identity.Name = "CorpDomain \ Albert"

System.Threading.Thread.CurrentPrincipal.Identity.Name = "CorpDomain \ Albert"

System.Security.Principal.WindowsIdentity.GetCurrent (). Name = "NT AUTHORITY \ NETWORK SERVICE"

Мой код клиента в основном:

MySvc.MyServiceClient svc = new MySvc.MyServiceClient();
svc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
Response.Write(svc.GetServiceHtml());

и на стороне WCF :

ServiceSecurityContext.Current.WindowsIdentity.Name = "NT AUTHORITY \ NETWORK SERVICE"

код на стороне сервера:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetServcieHtml()
{
    string name, link;
    StringBuilder html = new StringBuilder();

    html.Append(ServiceSecurityContext.Current.WindowsIdentity.Name);

    try
    {

        using (SqlConnection conn = GetDataConnection())
        {
            conn.Open();
            SqlCommand sqlcom = new SqlCommand("dbo.runsomeproc", conn);
            sqlcom.CommandType = CommandType.StoredProcedure;
            SqlDataReader sqlDataReader = sqlcom.ExecuteReader();


            while (sqlDataReader.Read())
            {
                // ** SOME CODE HERE **
            }

            conn.Close();
        }
    }
    catch (Exception ex)
    {
        html.AppendLine("<br><br>ERROR:" + ex.Message + " " + ex.InnerException);
        return html.ToString();
    }
    return html.ToString();
}

Примечание: Я получаю сообщение об ошибке: ОШИБКА: сбой входа для пользователя «CorpDomain \ ServerName01 $».

Есть идеи, что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 05 октября 2011

Не знаю, поможет ли это кому-нибудь, но у меня была эта проблема. Проблема была связана с настройкой идентификатора пула приложений, который мой сервис использовал в IIS. Если вы установите соответствующую личность там, вы должны быть хорошими. В моем случае по умолчанию было установлено NT Authority \ Network Service.

0 голосов
/ 29 мая 2012

Кроме того, исправьте меня, если я ошибаюсь, но в вашем клиентском web.config у вас есть поведение, которое установит уровень олицетворения на «Олицетворение», но вы не ссылаетесь на это поведение в своей конечной точке. Например:

  <client>
   <endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
    contract="MySvc.IMyService" name="NetTcpBinding_IMyService" />
  </client>

Должно быть:

  <client>
   <endpoint address="net.tcp://myurladdress/MyServices/Service.svc"
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyService"
    contract="MySvc.IMyService" name="NetTcpBinding_IMyService"
    behaviorConfiguration="ClientUserNameBehavior" />
  </client>
0 голосов
/ 03 ноября 2010

Вам также необходимо включить олицетворение на уровне обслуживания WCF.

Эта страница MSDN содержит все подробности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...