2010-05-20 2 views
0

У нас есть веб-служба .NET 3.5 (не WCF), работающая под IIS. Он должен использовать identity impersonate="true" и встроенную проверку подлинности Windows для аутентификации стороннего программного обеспечения. Кроме того, он подключается к базе данных SQL Server с использованием аутентификации ADO.NET и SQL Server (с указанием фиксированного идентификатора пользователя и пароля в строке подключения).Интегрированная проверка подлинности Windows в IIS, вызывающая сбой ADO.NET

Все работало отлично, пока база данных не была перенесена из SQL Server A для SQL Server B. (Не было таким же, как веб-сервер). Затем веб-служба будет бросить следующее исключение:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

Это ошибка только возникает, если идентификация олицетворяется в Web.config.

Опять же, строка подключения не изменилась и указала пользователя. Я протестировал строку подключения, и она работает как под олицетворенной учетной записью, так и под учетной записью службы (и с удаленной машины, и с сервера).

Что нужно изменить, чтобы заставить это работать с олицетворением?

EDIT:

Ремус Ruşanu указал нам в правильном направлении. Он дошел до Kerberos - SPN не были настроены для нового сервера. См. Также asp.net via kerberos integrated windows authentication to sql server. Спасибо!

ответ

3

При использовании олицетворения и доступа к ресурсу на другом хосте происходит делегирование (что миряне называют «двумя прыжками»). Поскольку делегирование по умолчанию ограничено, аутентификация завершается с ошибкой, если принудительное делегирование явно не включено.

Но подождите, вы говорите, я использую аутентификацию SQL, а проверка подлинности SQL не является ресурсом NTLM/Kerberos.Правда, говорит я, но вы также используете NAMED PIPES, а именованные каналы - это ресурс NTLM/Kerberos, поэтому происходит .

См. How to: Configure Client Protocols, чтобы убедиться, что SQL Server прослушивает TCP и Configuring Client Network Protocols для того, чтобы заставить клиента выбрать конкретный протокол (т. Е. Сначала не попробовать именованный канал). Вы также можете заставить TCP просто добавить tcp: перед именем сервера в строке подключения.

+0

Если я добавляю «tcp:», я получаю: «(поставщик: поставщик TCP, ошибка: 0 - соединение не может быть сделано, потому что целевая машина активно отказалась от него.)« Я попробовал это на своей локальной машине, где он будет работать, если Я снимаю «tcp:». – TrueWill

+1

Ваш сервер не настроен на прослушивание по TCP или не прослушивает порт по умолчанию –

0

Вы используете олицетворение в самом веб-сервисе?

Олицетворение в веб-службах работает на другом уровне, чем IIS. Чтобы получить от клиента к веб-службе, вы можете иметь идентификатор = выдавать себя за себя и получать токен пользователя из ServiceSecurityContext, даже с включенным анонимным режимом.

Чтобы олицетворять этот токен в веб-службе, получите WindowsCredential из ServiceSecurityContext и вызовите метод credential.Impersonate() в операторе using, разместив ваше соединение с базой данных внутри блока использования.

public class HelloService : IHelloService 
{ 
    [OperationBehavior] 
    public string Hello(string message) 
    { 
     WindowsIdentity callerWindowsIdentity = 
     ServiceSecurityContext.Current.WindowsIdentity; 
     if (callerWindowsIdentity == null) 
     { 
      throw new InvalidOperationException 
      ("The caller cannot be mapped to a WindowsIdentity"); 
     } 
     using (callerWindowsIdentity.Impersonate()) 
     { 
      // Access a file as the caller. 
     } 
     return "Hello"; 
    } 
} 

Кроме того, если вам нужна другая нога в процессе (т.е. фоновой службы находится на другом сервере), вам нужно будет использовать делегирование для распространения полномочий. Вы также можете сделать это декларативно. См. Эту статью для получения полной информации: http://msdn.microsoft.com/en-us/library/ms730088.aspx

+0

Я использую олицетворение, настроенное через IIS и Web.config для этой службы. Хотя потенциально ваш метод позволит нам олицетворять при вызове стороннего программного обеспечения, а не при вызове ADO.NET, это значительно усложнит код (который работал до того, как SQL Server был перемещен). Мы также не используем WCF, поэтому ссылка для делегаций не является релевантной. – TrueWill

+0

Я не знал, что вы не используете WCF, или что SQL-сервер никогда не был в одном поле. Код, который я разместил, является тем, что необходимо для WCF, поскольку олицетворение не выполняется через IIS. Извините за недоразумение и спасибо за разъяснение –

+0

Спасибо - я добавил примечание к исходному сообщению, чтобы уточнить. – TrueWill

0

Поскольку он работал, когда SQL Server находился в одном и том же поле, он может быть связан с транзакциями.

Возможно, он пытается использовать MSDTC, а олицетворенным пользователям не хватает прав.

Еще одна вещь, которую вы могли бы попробовать - это войти в систему на веб-сервере с пользователем, которого вы пытаетесь выдать, и посмотреть, можете ли вы затем подключиться к серверу sql.

+0

Я отредактировал вопрос, чтобы уточнить это. Ни SQL Server (старый, ни новый) не был в том же поле, что и веб-сервер. – TrueWill

0

Если Делегирование ваша проблема, обратитесь к этой статье для обеспечения ограниченного делегирования http://msdn.microsoft.com/en-us/library/ms730088.aspx

идти до самого низа, чтобы увидеть, как настроить учетную запись для ограниченного делегирования. Я знаю его статью WCF, но процесс настройки учетной записи для использования делегирования должен быть одинаковым.

для еще более подробной информации, перейдите сюда http://technet.microsoft.com/en-us/library/cc739587(WS.10).aspx

Кроме того, ваш SQL сервер обеспечения доступа TCP и доступ к нему, что путь, как пояснил Ремус.

Смежные вопросы