SSAS - динамическая защита измерений с использованием внешней .Net функции

OLAP, SSAS  SSAS Категория:  OLAP, SSAS
Опубликовал:         17.01.2012               print

SQL Server Analysis Services (SSAS) имеет развитую систему защиты данных, позволяющую различными методами ограничивать доступ как к целым членам измерений, так и к значениям ячеек. В Analysis Services предусмотрен объект безопасности под названием роль. Роли можно определять в многомерной базе данных, а затем этим ролям сопоставлять пользователей базы данных, тем самым ограничивая доступ к определенным членам измерений или ячейкам куба. Ограничение доступа к атрибутам измерений называется защитой измерений, которая может быть как безусловной, так и динамической.


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


Рассмотрим пример конкретный бизнес-сценарий. Итак, в реляционной базе данных (например, Oracle) рядом с основными таблицами-источниками для кубов создадим три служебные таблицы:
- OLAP_USER - список всех пользователей OLAP с указанием их бизнес-роли, статусом (активен, блокирован, уволен);
- OLAP_RESOURCE - перечень наименований всех атрибутов тех измерений многомерных баз данных, к которым требуется разграничивать права доступа пользователей; здесь же можно добавить поле "доступ по-умолчанию", значение которого будет автоматически тиражироваться для соответствующего атрибута и всех новых пользователей в следующей третьей таблице;
- OLAP_USER_ACCESS - доступ (0 или 1) каждого пользователя к отдельному атрибуту измерения с уточнением периода доступа с...по




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


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

CREATE OR REPLACE TRIGGER tr_olap_resource_insert AFTER INSERT ON olap_resource
FOR EACH ROW
BEGIN
  INSERT INTO olap_user_access ( id_olap_resource
                                ,id_olap_user
                                ,access_start
                               )
    SELECT :NEW.id_olap_resource
           ,id_olap_user
           ,TRUNC(SYSDATE)
      FROM olap_user ;
END ;


CREATE OR REPLACE TRIGGER tr_olap_user_insert AFTER INSERT ON olap_user
FOR EACH ROW
BEGIN
  INSERT INTO olap_user_access ( id_olap_user
                                ,id_olap_resource
                                ,access_start
                               )
    SELECT :NEW.id_olap_user
           ,id_olap_resource
           ,TRUNC(SYSDATE)
      FROM olap_resource ;
END ;
-- считается, что для полей access_start, access_expiry, resource_access 
-- таблицы olap_user_access определены значения по-умолчанию

Необходимо чтобы реляционный источник был постоянно доступен, виден серверу OLAP.


Теперь собственно создадим внешнюю .Net функцию, для чего в Microsoft Visual Studio создадим отдельный проект и напишем нижеследующий код:

Imports System
Imports System.Data
Imports System.Data.OleDb

Public Class OLAP_access
  Public Function CheckPermission(ByVal p_OLAP_user As String, _
                                  ByVal p_OLAP_resource As String, _
                                  ByVal p_OLAP_dimension As String, _
                                  ByVal p_OLAP_attrib As String) As Boolean
    Dim retVal As Boolean = False

    p_OLAP_user = p_OLAP_user.Trim
    p_OLAP_resource = p_OLAP_resource.Trim
    p_OLAP_dimension = p_OLAP_dimension.Trim
    p_OLAP_attrib = p_OLAP_attrib.Trim
    If p_OLAP_resource = "" Or p_OLAP_user = "" Or p_OLAP_dimension = "" Or p_OLAP_attrib = "" Then
      Return retVal
      Exit Function
    End If

    Dim queryString As String, connString As String = ""
    queryString = "SELECT u.*, r.id_olap_resource, r.olap_name, r.dimension_name, " _
                         "r.attribute_name, a.access_start, a.access_expiry, a.resource_access " _
                     "FROM olap_user u " _
                     "INNER JOIN olap_user_access a ON u.id_olap_user=a.id_olap_user " _
                     "INNER JOIN olap_resource r ON a.id_olap_resource=r.id_olap_resource " _
                        "WHERE u.olap_user_activity=''активный'' AND  u.user_name=''" p_OLAP_user "''" _
                             " AND r.olap_name=''" p_OLAP_resource "''" _
                             " AND r.dimension_name=''" p_OLAP_dimension "''" _
                             " AND r.attribute_name=''" p_OLAP_attrib "''" _
                             " AND TRUNC(SYSDATE) BETWEEN a.access_start AND a.access_expiry"

    Try
     ''считываем строку соединения с реляционной БД из внешнего xml-конфигурационного файла
      connString = get_ConnStringFromXML()
    Catch ex As Exception
    End Try

    If connString = "" Then
      Return retVal
      Exit Function
    End If

    Dim conn As New OleDbConnection
    conn.ConnectionString = connString
    Dim cmd As New OleDbCommand(queryString, conn)

    Try
      conn.Open()
    Catch ex As Exception
      conn.Dispose()
      Return retVal
      Exit Function
    End Try
    Try
      Dim rdr As OleDbDataReader = cmd.ExecuteReader()
      While rdr.Read()
        If rdr("resource_access")=1 Then
          retVal = True
          Exit While
        End If
        '' если запрос с реляционных настроечных таблиц вернул запись, 
        '' то считается данный пользователь имеет доступ к указанному OLAP-ресурсу
      End While
      rdr.Close()
    Catch ex As Exception
    End Try
    If conn.State = ConnectionState.Open Then
      conn.Close()
      conn.Dispose()
    End If

    Return retVal
  End Function


  Private Function get_ConnStringFromXML() As String
    ''строка соединения с реляционной базой данной хранится во внешнем xml-конфигурационном файле
    ''пример строки соединения MS OLEDB-провайдер for Oracle:
    ''connString = "Provider=msdaora; Data Source=someDataSource; User Id=someUser; Password=XXXXX;"

    ''пример строки соединения Oracle OLEDB-провайдер for Oracle:
    ''connString = "Provider=OraOLEDB.Oracle.1; Data Source=someDataSource; User Id=someUser; Password=XXXXX;"

    '' ....
  End Function
End Class

Внешняя CLR-процедура должна иметь качественный код, необходимо тщательно тестировать обработку ошибок, поскольку в дальнейшем с течением времени можно не сразу сообразить - почему у пользователей(я) в некоторой иерархии "пропали" элементы. На стороне реляционного источника, внутри функции можно завернуть самую сложную, экзотическую логику предоставления прав доступа к атрибутам измерений.


После компилирования .Net класса в DLL, добавим её в коллекцию сборок многомерной базы данных с соответствующим режимом олицетворения и набором полномочий. Для нашей сборки требуются неограниченные (unrestricted) полномочия, поскольку ей необходим доступ к внешним ресурсам (реляционной базе данных, конфигурационному xml-файлу). При внесении изменений в код класса с последующими перекомпиляцией сборки и deploy проекта OLAP на аналитическом сервере будет задействована обновленная версия DLL.




В проекте OLAP создадим единственную роль Staff.role и включим в неё учетные записи всех потенциальных пользователей, раздадим доступ на чтение для измерений и куба. Эта роль нужна для того, чтобы пользователи в принципе могли достучаться до куба. Добавление новых пользователей в Staff.role можно автоматизировать, разработав соответствующий скрипт и включив его в SSIS-пакет обработки куба.


IIF( OLAP_access.CheckPermission(USERNAME(), <Наименование_OLAP>, <Наименование_измерения>, <Наименование_атрибута>),
     <Наименование_измерения>.<Наименование_атрибута>.MEMBERS, {} )

где вместо угловых скобок подставьте ваши наименования.



В случае, если внешняя .Net функция для текущего пользователя, указанного куба, измерения, атрибута вернёт значение True, то пользователю будут доступны все элементы атрибута измерения. В противном случае - пользователю вернется пустое множество {}.


Если в реляционных таблицах блокируется доступ (или, наоборот, предоставляется доступ) пользователя к указанному OLAP-ресурсу или удаляется пользователь, то, чтобы изменения вступили в действие на стороне SSAS-сервера, необходимо сбросить многомерный кэш.


Энергия идеи   dvbi.ru                    Последнее изменение: 2017-10-15 16:27:32Z         Возрастная аудитория: 14-70         Комментариев:  0
Теги:  DLL для SSAS
Связанные статьи:

Пожалуйста, проголосуйте и ниже поставьте лайк:   rating
0 0 0


  Comments


Следующая статья:    Знакомство с книгой MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook
Предыдущая статья:  SSAS - конверсия валют