Доступ заборонено, коли код виконується віддалено як служба wcf

Слідуючи попередньому запиту код у службі WCF, я отримую виключення Доступ заборонено .

using (SPSite newspSite = SPContext.Current.Site)
{
     foreach (SPService service in newspSite.WebApplication.Farm.Services)
     {

             foreach (SPJobDefinition jobDefinition in service.JobDefinitions)
             {

                  if (jobDefinition.Name == "Word Automation Services")
                  {
                         jobDefinition.RunNow();
                         break;
                  }

             }
      }
}

Цей код дає проблеми, оскільки неможливо віддалено запустити методи Microsoft.SharePoint.Administration . Обхідні шляхи для цього, як зазначено тут , працюють лише для SPWebService і недоступний для WordService .

Рішення пробували:

a) Пробували обгортання коду всередині

SPSecurity.RunWithElevatedPrivileges(delegate{ [code] })

Але отримуємо ту ж помилку.

Знімок екрана

Manged для налагодження служби,

enter image description here

Чи існують альтернативи або обхідні шляхи ...

0
@Flowerking Ви дійсно уточнюєте своє попереднє запитання, і було б більш доцільним продовжувати редагування початкового питання. Я об'єднав це питання з вашим оригінальним запитанням, щоб уникнути дублювання. Дякую.
додано Автор Liron Yahdav, джерело
Коли ви загорнули в RWEP, ви змінили SPSite newspSite = SPContext.Current.Site на SPSite newspSite = новий SPSite (SPContext.Current.Site.Id) ? До речі, НІКОЛИ не пишіть , використовуючи (SPSite newspSite = SPContext.Current.Site) , оскільки це дозволить вилучити SPSite, яким ви не керуєте.
додано Автор binOr, джерело
Ви пробували обхідний шлях, згаданий у статті, на яку ви посилаєтеся? Пам'ятайте, SPWebService не має абсолютно ніякого відношення до веб-служб. І ваш код не має нічого спільного з WordService, але тільки з запуском завдання таймера (що трапляється з WordService)
додано Автор binOr, джерело
Чи присвоїли Ви права облікового запису служби в програмі Word Automation Services?
додано Автор David Bryson, джерело
@SPDoctor Дякуємо за це !!!
додано Автор Antzi, джерело
Як це зробити? Я не впевнений, що ви пропонуєте. Не могли б ви, будь ласка, кинути трохи більше світла.
додано Автор Antzi, джерело
myService.RemoteAdministratorAccessDenied = false; це властивість доступне лише для об'єкта SPWebService і недоступне за допомогою WordService , тому я не можу його використовувати !
додано Автор Antzi, джерело
Я використовую SPSite newspSite = новий SPSite (siteurl) у консольному додатку. І змінив його на вище для розгортання WCF, думаючи, що це може бути причиною помилки доступу заперечується.
додано Автор Antzi, джерело
В порядку. Я змінив його зараз і спробував перерозподілити, але він все ще обертається тим самим виключенням "Доступ заборонено". І спасибі за відгук про використання оператора. Я міняю свій інший код відповідно.
додано Автор Antzi, джерело
Її використання вікна входу для аутентифікації, я не використовую spcontext в будь-якому місці коду, його веб-служби створені за допомогою CSKDev wcf послуги visualstudio шаблон. Я не використовую жодних конфігураційних файлів.
додано Автор Antzi, джерело
Декілька запитань: чи є це сайтом авторизації претензій? користувач має доступ до сайту, на якому працює служба? Служба намагається використати або прочитати ідентифікацію користувача з SPContext? є "клієнт" додаток SharePoint, консоль або інше? Ви використовуєте динамічну конфігурацію? (див. MSDN msdn.microsoft.com/en-us/ library/ff521581 (office.14) .aspx )
додано Автор cupe, джерело
Див. Мою відповідь на ваше попереднє запитання і, будь ласка, не відкривайте нове питання, просто продовжуйте старе.
додано Автор phunehehe, джерело
Я не вірю, що ваш код працює в консольному додатку, оскільки SPContext.Current покладається на HttpContext.Current, і це недоступне в консольному додатку.
додано Автор Nick Alger, джерело

8 Відповіді

Я мав ту ж саму проблему і отримав його для роботи в двох напрямках. Необхідно зробити обліковий запис пулу додатків, який запускає службу WCF, або адміністратор на сервері SharePoint, або зробити його адміністратором ферми. Ви також повинні надати цьому обліковому запису права на базі даних контенту, а також у базі даних конфігурацій SharePoint. З якоїсь причини я знаходжу, що я також повинен дати йому дозволи на базі даних SharePoint_Admin_guid.

Хто-небудь знає спосіб примусити його працювати з меншими дозволами?

Дякую, Сабін

2
додано
Це дійсно проблема з дозволом, але чи можливо розгорнути службу WCF без включеного імпресіонації? В даний час я використовую атрибути заводу wcf [BasicHttpBindingServiceMetadataExchangeEndpointAttribute] , тому єдиним способом для мене є створення віддаленого облікового запису за допомогою служби адміністратора ферми. Зараз він працює, але я сумніваюся, що він буде працювати при розгортанні.
додано Автор Antzi, джерело

Я потрапив до багатьох подібних проблем, працюючи зі службами WCF, розміщеними всередині SharePoint. Смуги, здається, збільшуються, коли ви додаєте претензії для авторизації. Я часто повертався до використання asmx послуг. Існують відомі проблеми з динамічною конфігурацією служб WCF SOAP всередині SharePoint ( зазначено тут ). Якщо це доречно, ви можете спробувати налаштувати його як службу WCF REST. Є запис у блозі тут , де хтось потрапив у проблему з подібними симптомами і що вони зробили для її вирішення.

1
додано
+1 Дякуємо за відповідь, посилання є інформативними. Проте проблема в моєму коді, перевірте оновлений запит.
додано Автор Antzi, джерело

Є кілька обхідних шляхів, про які я можу подумати.

Варіант 1) Не використовуйте службу WCF, використовуйте клієнт OM для запису простого пункту "прапор" у список. Пов'яжіть робочий процес зі списком прапорів, який починається після додавання нових елементів. Робочий процес може запустити завдання таймера.

Option 2) Code an ItemAdded event hander and do the conversion with the ConversionJob class. Example

1
додано
Так, я повинен перевірити асинхронно до завершення перетворення.
додано Автор Antzi, джерело
Так, це те, що я думав робити в першу чергу, але вимога полягає у використанні Sharepoint як сервера для перетворення docx в pdf або інші формати, дозволяючи сервісу wcf, які роблять перетворення і повертають файл як потік. Отже, чи мій підхід повністю помиляється? Ця вимога є лише частиною всього рішення, оскільки слово генерується також динамічно.
додано Автор Antzi, джерело
Я бачу. Я не розумів, що потрібно відправити файл назад. Схоже, вам потрібно чергу повідомлень (або подібний механізм), щоб клієнт міг отримувати сповіщення (або перевіряти, щоб побачити), коли перетворення завершено. Думаю, синхронний виклик дасть вам кошмари.
додано Автор cupe, джерело

По-перше, ви створили службу WCF за допомогою CKSDEV, який створює WCF на базі сервісу SharePoint WCF (чиста, повна підтримка SharePoint, немає необхідності в конфігураційному файлі), або "звичайна" служба WCF, розгорнута в папці ISAPI?

Також я бачу кілька проблем:

First, To consume a WCF service running in SP, you always need to set the impersonation level in the consuming code:

var client = new YourServiceClient();
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Second, elevation only works if you actually create a new context inside it,

SPSecurity.RunWithElevatedPrivileges(delegate{
using (SPSite newspSite = SPContext.Current.Site)    
  {
   //your elevated actions (not actually elevated
  }
});//the current context is disposed!!

не створює виділений об'єкт сайту, що ще гірше, він містить фактичний поточний контекст!

SPSecurity.RunWithElevatedPrivileges(delegate{
  using (SPSite newspSite = new SPSite(SPContext.Current.Site.Url))    
  {
   //your elevated actions
  }
});

Last: Anything running at the farm level being called from a webapp will not work, seeing as even under elevated prviliges the code will run as the web app's apppool, which is not a farm admin (I hope :-D).

Зателефонуйте до служби під центральним адміністратором, який запускає під пулом додатків цього сайту (обліковий запис ферми). Це означає, що користувач, який використовує код, потребує доступу на рівні ферми, тому, ймовірно, він не працюватиме.

У минулому я обійшов це, призначивши обліковий запис адміністратору сайту кореневої колекції веб-застосунку. Це обліковий запис служби (тому в AD не має жодних дозволів на вхід у систему: вхід локально, вхід як пакет/служба тощо) Цей користувач повинен бути членом адміністративної групи ферми. Потім скористайтеся наступним кодом, щоб отримати цього користувача, а потім запустити код, як цей користувач:

SPSecurity.RunWithElevatedPrivileges(delegate{
  using (SPSite elevatedSite = new SPSite(SPContext.Current.Site.Url))    
  {
    using (SPSite newspSite = new SPSite(elevatedSite.Url, elevatedSite.SecondaryContact.UserToken))    
    {
     //your elevated actions, running as the secondary admin
    }
  }
});

P.S. Служба конвертації документів виконується асинхронно, тому після звільнення завдання, ви не знаєте, коли вона дійсно виконується, так що ви не можете, наприклад, завантажити отриманий документ відразу після.

1
додано
Пробували все, як припускали, все одно отримували те ж виняток дивно. Я думав, що ваш останній підхід позбудеться цього для мене, але до мого здивування нічого не працює на моєму шляху.
додано Автор Antzi, джерело
І так, я використовую CSKDev шаблон для створення служби, і весь конфіг. секція gud як я можу використовувати інші операції на сервісі. Але виключення access denied дає лише операція із зазначеним вище кодом.
додано Автор Antzi, джерело
+1 Дякуємо Колін за відповідь. як ви можете бачити в розділі конфігурації <�поводження ім'я = "NewBehavior0"> правильно налаштовувати себе, а також я впевнений, що ваша друга пропозиція. Я повинен перевірити вашу останню пропозицію, щоб побачити, якщо він працює.
додано Автор Antzi, джерело

Я вважаю, що ваша служба WCF розміщена в SharePoint. Чи використовували ви облікові дані мережі для своєї служби? Також переконайтеся, що ви не є доменами при виклику сервісу WCF.

Будь ласка, скажіть мені, якщо я помиляюся, але здається, ви насправді намагаєтеся змусити роботу Word Automation перетворення працювати, чи не так? Вам не слід використовувати щось подібне (щоб запустити певну роботу конверсії):

string siteUrl = "http://sp.local";
    string wordAutomationServiceName = "Word Automation Services";
    using (SPSite spSite = new SPSite(siteUrl))
    {
        ConversionJob job = new ConversionJob(wordAutomationServiceName);
        job.UserToken = spSite.UserToken;
        job.Settings.UpdateFields = true;
        job.Settings.OutputFormat = SaveFormat.PDF;
        job.AddFile(siteUrl + "/Shared%20Documents/Test.docx", siteUrl + "/Shared%20Documents/Test.pdf");
        job.Start();
    }
1
додано
Це саме те, що мій код, але він додає завдання перетворення в чергу завдань. І перетворення починається, коли завдання таймера перетворення заплановано для запуску. Замість цього, я намагаюся змусити його використовувати мій вище код після запуску роботи, як у вашому коді - який працює в консольному додатку, але дає проблеми, коли викликається віддалено :(
додано Автор Antzi, джерело
Так, його розміщення на sharepoint, будь ласка, перевірте моє інше питання для cofig. та інші деталі. Я використовую imperosonation з ntlm та його робочий штраф для інших операцій для тієї же служби. Але для операції, що містить вищевказаний код, видається помилка Access denied .
додано Автор Antzi, джерело
побачити моє редагування вище!
додано Автор Michael Lee, джерело

Виходячи з деяких інших коментарів, що робити, якщо ви створили додатковий веб-сервіс, який просто запускає завдання таймера на вимогу? Посилайтеся на цю нову послугу (як якщо б вона була розміщена в центральній веб-застосунку адміністратора) з існуючої служби WCF. Код, який запускається всередині нової служби, може працювати як підвищений, якщо це необхідно. Думаю, що вирішити питання про доступ, яким відмовлено.

0
додано
Або може бути, якщо я створити нову послугу, як ви запропонували в якості. Я дам йому спробувати і буде оновлюватися тут відповідно .. Велике спасибі за допомогу!
додано Автор Antzi, джерело
Крім того, ви можете отримати посилання на ферму за допомогою SPFarm.Local, вам не доведеться підніматися по ланцюжку об'єктів з поточного сайту. SPFarm.Local.Services
додано Автор cupe, джерело
ASMX або WCF не має значення, це адміністративний код, який ви намагаєтеся запустити, для чого потрібні адміністративні права адміністратора (просто перевірте методи, які ви закликаєте за допомогою ILSpy, щоб побачити перевірку безпеки в фактичному коді SharePoint)
додано Автор phunehehe, джерело

Я мав подібну проблему, намагаючись підключитися до веб-служби профілю користувача. Я міг би підключитися до веб-служби, але отримуватиме помилку про заборону доступу кожного разу, коли я її викликаю.

Зрештою, виявилося, що альтернативні відображення доступу не були правильно налаштовані для URL, з яким я намагався отримати доступ до сайту. Я б двічі перевірив альтернативні відображення доступу для URL-адреси, з якою ви намагаєтеся з'єднатися.

Вибачте, якщо це не допоможе.

0
додано

Я стикаюся з подібною проблемою, але різниця в тому, що у мене є код роботи конверсії в веб-частині. Це дія, ініційована користувачем.

Я спробував надати дозволу облікового запису пулу додатків на послуги автоматизації слів у центральній системі адміністрування. Я також надав права власника db-власника на базу даних налаштувань sharepoint. (Швидкий q тут: які права я повинен дати?)

Будь ласка, дайте мені знати, що не так, як я був застряг з нею протягом тривалого часу.

Код: string wordAutomationServiceName = "Служби автоматизації Word";

                    ConversionJob job = new ConversionJob(wordAutomationServiceName);
                    job.UserToken = iSPSite.SystemAccount.UserToken;
                    job.Settings.UpdateFields = true;
                    job.Settings.OutputFormat = SaveFormat.Automatic;
                    job.AddFile(web.Url + "/" + Constants.collatedArticlesLib + "/" + lblColDocName.Text,
                        FileToSave);
                    job.Start();

                    foreach (var service in iSPSite.WebApplication.Farm.Services)
                    {
                        if (service.TypeName == "Word Automation Services")
                        {
                            foreach (var jobDefinition in service.JobDefinitions)
                            {
                                if (jobDefinition.Name == "Word Automation Services")
                                {
                                    **jobDefinition.RunNow();**
                                    break;
                                }
                            }
                        }
                    }

                    while (true)
                    {
                        Thread.Sleep(5000);
                        ConversionJobStatus status = new ConversionJobStatus("Word Automation Services", job.JobId, null);
                        if (status.Count == status.Succeeded + status.Failed)
                        {
                            break;
                        }
                    }
0
додано