Разрешение на предоставление нового семейства сайтов через рабочий процесс - PullRequest
1 голос
/ 03 февраля 2010

Я застрял в очень странной ситуации.

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

--- другой код опущен для ясности ----

SPSiteCollection.Add ()

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

Доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED)) в Microsoft.SharePoint.SPGlobal.HandleUnauthorizedAccessException (UnauthorizedAccessException бывший) в Microsoft.SharePoint.Library.SPRequest.CreateSite (Guid gApplicationId, String bstrUrl, Int32 lZone, Guid gSiteId, Guid gDatabaseId, Строка bstrDat

после долгих поисков и поисков я обнулил разрешение на учетную запись Applicaiton Pool.

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

Когда мое веб-приложение работает под учетными данными пула приложений Central Admin, оно имеет все права доступа к базе данных конфигурации. Но когда я работаю под любым другим удостоверением пула приложений, у которого меньше разрешений. он выдает исключение, даже если я даю разрешение DBO учетной записи пула приложений в базе данных конфигурации.

В журнале событий моего приложения есть следующая запись: -

Источник события: Windows SharePoint Услуги 3 Категория: База данных Код события: 3760 Дата: 3.02.2010 Время: 2:36:16 Пользователь: N / A Компьютер: SHAREPOINT20 Описание: База данных SQL «SharePoint_Config» включена Экземпляр SQL Server «houspsr001» не найденный. Дополнительная информация об ошибке из SQL Server включен ниже.

Невозможно открыть базу данных «SharePoint_Config» запрошенный авторизоваться. Ошибка входа Ошибка входа для пользователя 'DOMAIN \ WebAppPool'.

Для получения дополнительной информации см. Справку и Центр поддержки на http://go.microsoft.com/fwlink/events.asp.

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

Есть ли обходной путь для этого ....?

Мой вопрос

Ответы [ 2 ]

1 голос
/ 20 декабря 2010

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

Для этого рекомендуется использовать SecureString. Как это можно использовать в сочетании с SecureString, можно посмотреть на MSDN . Основным отличием решения Sudhir является использование другой перегрузки LogonUser, а именно

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String username, String domain, 
                                      IntPtr password, int logonType, 
                                      int logonProvider, ref IntPtr token);

и используйте его следующим образом (этот код взят из MSDN):

// Marshal the SecureString to unmanaged memory.
passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(pwdSecureString);

// Call LogonUser, passing the unmanaged (and decrypted) copy of
// the SecureString password.
returnValue = LogonUser(userName, domainName, passwordPtr,
                        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, 
                        ref tokenHandle);

// Zero-out and free the unmanaged string reference.
Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);

Таким образом, пароль шифруется только непосредственно перед тем, как мы используем его для входа в систему. После этого незашифрованный пароль немедленно удаляется из памяти.

1 голос
/ 09 февраля 2010

Наконец, проблема с отказом в доступе была решена.Как я указывал в своем предыдущем электронном письме, проблема была связана с недостаточным разрешением для идентификатора пула приложений.

  • Центральный администратор работал под другим идентификатором пула приложений
  • Веб-приложения работаютпод другим идентификатором пула приложений.

Мой рабочий процесс использовал ElevatedPrevilages для предоставления семейства сайтов, и он получал отказ в доступе из базы данных, поскольку у него не было разрешения изменять базу данных SharePoint_Config.

Решение Чтобы решить эту проблему, мне пришлось выдать себя за идентификатор пула приложений Центрального администратора.Вот обязательный метод для олицетворения пользователя пула приложений Central Admin.

   #region Application Pool Identity Impersonate

        protected static WindowsIdentity CreateIdentity(string User, string Domain, string Password)
        {
            // The Windows NT user token.
            IntPtr tokenHandle = new IntPtr(0);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_NETWORK = 3;

            tokenHandle = IntPtr.Zero;

            // Call LogonUser to obtain a handle to an access token.
            int returnValue = LogonUser(User, Domain, Password,LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,out tokenHandle);

            //Check if the logon user method succeeded
            if (returnValue <= 0)
            {
                int ret = Marshal.GetLastWin32Error();
                throw new Exception("LogonUser failed with error code: " + ret);
            }

            //System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);

            //The WindowsIdentity class makes a new copy of the token.
            //It also handles calling CloseHandle for the copy.
            WindowsIdentity id = new WindowsIdentity(tokenHandle);
            CloseHandle(tokenHandle);
            return id;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern int LogonUser(
            string lpszUsername,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            out IntPtr phToken
            );
        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern int ImpersonateLoggedOnUser(
            IntPtr hToken
        );

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern int RevertToSelf();

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int CloseHandle(IntPtr hObject);

        #endregion

И тогда мой код для создания семейства сайтов выглядит так: -

//Impersonate the logged in user, ApplicationUser, LoginDomain and Password are exposed as property of the class.

WindowsImpersonationContext wiContext = CreateIdentity(this.ApplicationPoolUser, this.LoginDomain, this.SystemPassword).Impersonate();



//Provision new site collection and update the property for new site collection url.

using (SPSite newSiteCollection = spSiteColl.Add(SUGGESTEDURL, TITLE, DESC, LCID, WEBTEMPLATE, PRIMARYOWNER.LoginName, PRIMARYOWNER.Name, PRIMARYOWNER.Email, SECONDARYOWNER.LoginName, SECONDARYOWNER.Name, SECONDARYOWNER.Email))

{

this.SUGGESTEDURL = newSiteCollection.Url;

}



//Reset the impersonation.

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