Member 12923802 Ответов: 3

Невозможно получить доступ к SQL server из службы WCF (Windows authenticated) из клиента (консольного приложения) на языке C#


Здесь я использую
1) служба WCF (аутентификация Windows и олицетворение)
2) Sql server (аутентификация Windows)
3) Консольное Приложение (Клиент)
Все они находятся в одном домене

Я потребляю аутентифицированную службу WCF windows из консольного приложения (клиента), поэтому, когда я пытаюсь получить доступ к SQL server из консольного приложения с помощью службы WCF, она показывает мне ошибку :
Exception In Account Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.


Мой сценарий таков
моя служба WCF и SQL server находятся в одной системе (предположим, Система A), а мое консольное приложение(Мой клиент) - в другой системе (предположим, система B).
когда мой клиент (система B) отправляет запрос, он успешно попадает в мою службу, но когда служба пытается получить доступ к SQL server, она показывает ошибку:
Exception In Account Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.


Что я уже пробовал:

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

static void Main(string[] args)
       {
           try
           {
               ServiceClient obj = new ServiceClient();
               obj.ClientCredentials.Windows.AllowedImpersonationLevel =
                       System.Security.Principal.TokenImpersonationLevel.Impersonation;
               obj.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
                  AccModel objAccModel = new AccModel();
                  objAccModel.ACC_No = "jkh90";
                  objAccModel.Remark = "dsdsadasd";
                  objAccModel.ACC_Code = "AA";
                  var strflight = obj.Acc_Validate(objAccModel);
           }
           catch (Exception ex)
           {

               Console.Write(ex.Message);
           }

       }


Мой серверный код (служба WCF)

public string Acc_Validate(ACCModel objACCModel)
       {
               try
               {

                   using (WindowsImpersonationContext ctx = WindowsIdentity.GetCurrent().Impersonate())
                   {
                     SqlParameter[] parameter = {
                                          new SqlParameter("@CMD","ACCVALIDATE"),
                                          new SqlParameter("@ACC_No",objACCModel.ACC_No),
                                          new SqlParameter("@ACC_Code",objACCModel.ACC_Code),
                                          new SqlParameter("@PNRIDOUT", SqlDbType.NVarChar,800) {Direction = ParameterDirection.Output}
                                          };
               strStatus = SQLHelper.ExecuteNonQueryTwoOutputResult(SQLHelper.ConnectionStringLocalTransaction, CommandType.StoredProcedure, DBConstants.PRIU_ACC_DETAILS,  "@PNRIDOUT", parameter);
                   }
               }
               catch (Exception ex)
               {
                   ClsLogging.writefile("Errorrrrrrrrrrr " + ex.Message, ClsLogging.LogType.BTA_Service_Exception);
               }

               }


Служба WCF (файл веб-конфигурации)

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5"/>
    <pages controlRenderingCompatibilityVersion="4.0"/>
    <httpCookies httpOnlyCookies="true"/>
    <authentication mode="Windows">
    <identity impersonate="true"/>
  
  <connectionstrings> 
    <add name="Connection" connectionString="Initial Catalog=ACCDB;Data Source=*****;Integrated Security=True;"/>
  
  <system.servicemodel>
    <services>
      <service name="Service.Service" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="Service.IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      
    
    <bindings>
      <basichttpbinding>
        <binding name="TransportSecurity">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"/>
            
          
        
      
    
    <behaviors >
      <servicebehaviors>
        <behavior name="ServiceBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          <serviceMetadata httpGetEnabled="true"/>
          <serviceAuthorization impersonateCallerForAllOperations="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="false" serviceAuthorizationAuditLevel="SuccessOrFailure" messageAuthenticationAuditLevel="SuccessOrFailure"/>
          <serviceThrottling maxConcurrentCalls="500" maxConcurrentInstances="100" maxConcurrentSessions="200"/>
        
      
    
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>
  
  <system.webserver>
    <validation validateIntegratedModeConfiguration="false" />
    <httpprotocol>
      <customheaders>
        <add name="X-Content-Type-Options" value="nosniff"/>
      
    
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>

3 Ответов

Рейтинг:
2

Member-515487

Измените свой код с помощью следующих материалов

//client
                ServiceClient obj = new ServiceClient();
              
  obj.ClientCredentials.Windows.AllowedImpersonationLevel = 
     System.Security.Principal.TokenImpersonationLevel.Delegation; // other stuff remove which you did for Test purpose
              
                   AccModel objAccModel = new AccModel();
                   objAccModel.ACC_No = "jkh90";
                   objAccModel.Remark = "dsdsadasd";
                   objAccModel.ACC_Code = "AA";
                   var strflight = obj.Acc_Validate(objAccModel);


это решит вашу проблему


Рейтинг:
0

OriginalGriff

Посмотрите на сообщение об ошибке:

Exception In Account Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
Ваша служба WCF не работает как "обычный пользователь" - она работает под специальным анонимным логином. Поэтому, когда вы пытаетесь использовать интегрированную безопасность как часть строки подключения, она терпит неудачу, потому что не позволяет анонимным пользователям получить доступ к БД (и совершенно правильно!)

Используйте комбинацию имени пользователя и пароля SQL (не sa однако войдите в систему, ради Бога) и измените строку подключения, чтобы отразить это. Затем он должен подключиться без проблем.


Member 12923802

Я не могу использовать аутентификацию Sql (имя пользователя и пароль) для своей базы данных. Требование для проверки подлинности windows для моей базы данных

OriginalGriff

Затем вам придется запустить свой сервис под учетной записью пользователя, которую примет база данных.

Member 12923802

мы уже работаем с учетной записью пользователя, которая имеет права на SQL, но все еще получает пропуск как "NT AUTHORITY\ANONYMOUS" в то время как SQL

OriginalGriff

Ваша служба WCF-нет. Возможно, ваше консольное приложение так и есть, но ваша служба не работает под учетной записью пользователя.

Рейтинг:
0

Richard Deeming

Похоже, вы забыли добавить OperationBehavior атрибут к вашему методу обслуживания:

При олицетворении для всех операций свойству Impersonation атрибута OperationBehaviorAttribute, применяемому к каждому методу, также должно быть присвоено значение Allowed или Required.

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Acc_Validate(ACCModel objACCModel)

Основываясь на этой статье, вы не должны нуждаться в WindowsImpersonationContext.