Разрешение контрольного отчета на основе параметров в службах Reporting Services - PullRequest
4 голосов
/ 29 марта 2012

Предположим, у нас есть отчет SalesSummary для большого отдела. В этом отделе есть много небольших команд для каждого продукта. Люди должны иметь возможность видеть информацию о своем собственном продукте, а не о продуктах других команд. У нас также есть одна группа доменов для каждой из этих команд.

Копирование отчета SalesSummary для каждой команды и установка разрешения - не лучший вариант, так как у нас много продуктов. Я думал использовать код, подобный приведенному ниже, на RS, но он не работает. По-видимому, System.Security.Principal.WindowsPrincipal по умолчанию отключен на RS.

Public Function isPermitted() As Boolean
   Dim Principal As New System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent())
   If (Principal.IsInRole("group_prod")) Then
      Return true
   Else
      Return false
   End If
End Function

Я также подумал, что могу отправить userID с RS на SQL-сервер, и внутри моего SP я могу использовать код, подобный приведенному ниже, для запроса активной директории. Это также не работает из-за ограничений безопасности.

SELECT
* 
FROM OPENQUERY(ADSI,'SELECT cn, ADsPath FROM ''LDAP://DC=Fabricam,DC=com'' WHERE objectCategory=''group''')

Есть ли более простой способ достичь этой цели?

Спасибо за помощь!

Ответы [ 2 ]

3 голосов
/ 29 марта 2012

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

Ваш второй подход будет работать, но требует соответствующих разрешений для вашего SQLУчетная запись службы сервера для запроса Active Directory.

Другой подход заключается в сохранении копии членства в группе или пользовательских разрешений в таблице SQL.Эта таблица может быть обновлена ​​вручную или с помощью автоматизированного процесса.Затем вы можете легко включить это как в доступные параметры, так и в запросы к основным данным.

1 голос
/ 14 мая 2012

Итак, я получил этот код:

        PrincipalContext domain = new PrincipalContext(ContextType.Domain, "AD");
        UserPrincipal user = UserPrincipal.FindByIdentity(domain, identityName);
        //// if found - grab its groups
        if (user != null)
        {
            PrincipalSearchResult<Principal> _groups = null;
            int tries = 0;
           //We have this while because GetGroups sometimes fails! Specially if you don't
           // mention the domain in PrincipalContext
            while (true)
            {
                try
                {
                    _groups = user.GetGroups();
                    break;

                }
                catch (Exception ex)
                {
                    logger.Debug("get groups failed", ex);
                    if (tries > 5) throw;
                    tries++;
                }
            }

            // iterate over all groups, just gets groups related to this app
            foreach (Principal p in _groups)
            {
                // make sure to add only group principals
                if (p is GroupPrincipal)
                {
                    if (p.Name.StartsWith(GROUP_IDENTIFIER))
                    {
                        this.groups.Add((GroupPrincipal)p);
                        this.groupNames.Add(p.Name);
                    }
                }
            }
          }

Теперь, когда у вас есть список связанных групп, вы можете проверить этот список, чтобы авторизовать пользователя!

...