2012-04-04 8 views
4

У меня есть метод службы WCF, который вызывает хранимую процедуру SQL. Я разрабатываю с использованием IIS 5 (не могу этого сделать, II6/7 недоступно)Задача TPL в службе WCF не использует правильные учетные данные безопасности IIS (соединение SQL)

Чтобы получить некоторую прибыль, я делаю несколько асинхронных вызовов этой сохраненной процедуры, помещая вызов в переменную aC# Задача TPL.

При запуске в качестве задачи, я получаю исключение SQL ... «Войти не удалось. Логин от ненадежного домена и не может быть использована с проверкой подлинности Windows»

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

Мне кажется, что учетные данные для виртуальной папки IIS (WCF) не делегируются заданию? Любые идеи, как я могу указать учетные данные для потока задач TPL, то есть использовать то же, что и родительский и т. Д.?

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

Ваша помощь оценена.

+0

Вы используете проверку подлинности Windows? – Aliostad

+0

Я имею в виду проверку подлинности Windows для IIS. – Aliostad

+0

Да, я использую windows auth для IIS, а строка SQL connect указывает SSPI и т. Д. –

ответ

5

У вас есть два варианта.

1) Выбирает все приложение в постоянно протекающей личность с помощью:

<runtime> 
    <alwaysFlowImpersonationPolicy enabled="true"/> 
</runtime> 

Это имеет побочный эффект накладных расходов и опасность случайного выполнения некоторые непредусмотренный кода с привилегиями в настоящее время вызывающего пользователя, а не идентификатор приложения. Я бы лично избегал этого и пошел с № 2, где вы явно отказались.

2) Захват WindowsIdentity перед установкой ваших задач TPL и явно выдавать себя, где вам нужно сделать звонки, используя Impersonate + WindowsImpersonationContext:

public void SomeWCFOperation() 
{ 
    WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(); 

    Task.Factory.StartNew(() => 
    { 
     // some unpriviledged code here 


     using(WindowsImpersonationContext impersonationContext = currentIdentity.Impersonate()) 
     { 
      // this code will execute with the priviledges of the caller 
     } 

     // some more unpriviledged code here 
    }); 
} 
+0

Привет Дрю. Хороший ясный ответ, рад, что вы сразу поняли мою проблему. Я не смогу попробовать это решение до самой Пасхи, но как только я это сделаю, я постараюсь ответить на этот вопрос. Вы должны потратить свои 50 бонусных баллов мудро, хотя я могу добавить ;-) –

+0

Да, я могу подтвердить, что это работает отлично (ну вариант 2). Еще раз спасибо –

+0

Рад помочь. Счастливое кодирование! –

0

качестве другого решения проблемы, вы можете создавать расширения для TPL следующим :

public static class TaskFactoryExtensions 
{ 
    public static Task StartNewImpersonated(this TaskFactory taskFactory, Action action) 
    { 
     var identity = WindowsIdentity.GetCurrent(); 
     return taskFactory.StartNew(() => 
     { 
      using (identity.Impersonate()) 
      { 
       action(); 
      } 
     }); 
    } 

    public static Task<TResult> StartNewImpersonated<TResult>(this TaskFactory taskFactory, Func<TResult> function) 
    { 
     var identity = WindowsIdentity.GetCurrent(); 
     return taskFactory.StartNew<TResult>(() => 
     { 
      using (identity.Impersonate()) 
      { 
       return function(); 
      } 
     }); 
    } 
} 

Вы должны были бы назвать эти новые методы вместо стандартных методов StartNew.

Недостатком этого является то, что существует множество способов переопределить.