2011-02-07 2 views
3

Я пытаюсь реализовать привилегии с помощью NHibernate, и то, что я хочу сделать, каждый раз, когда есть запрос Select, проверьте, что такое тип возврата, и если это тип с включенной безопасностью (например, счета-фактуры), я хочу добавьте ограничения на объект ICriteria, чтобы ограничить получение только определенных записей (если пользователь прочитал все или прочитал собственные привилегии).NHibernate PreSelect?

мне удалось реализовать такого рода льготы для вставки и обновления с помощью

NHibernater.Event.IPreUpdateEventListener 
NHibernater.Event.IPreInsertEventListener 

, но, к сожалению, IPreLoadEventListener вызывается после того, как база данных опрашивается, и поэтому отходы, как фильтрация будет осуществляться локально на компьютер, а не база данных.

Кто-нибудь знает, предоставляет ли NHibernate какое-либо событие, которое вызывается до выполнения запроса?

ответ

2

Если вы можете использовать его, проверить Rhino.Security Это именно то, что вы пытаетесь сделать. Даже если вы не можете его использовать, вы можете увидеть его реализацию этой проблемы.

+0

Я пытаюсь выяснить, как его использовать, но с реальным трудным временем :(прямо сейчас я думаю о реализации решения Фредерика с фильтрами. –

+0

@LnDCobra, да, документации об этом нет. – Vadim

2

Не можете ли вы добиться этого, используя фильтры?

Более подробную информацию можно найти here

Я использовал это в сочетании с перехватчики в проекте шахты:

У меня есть некоторые объекты, где каждый пользователь может создавать экземпляры из, но только тот пользователь, который создал их, должен иметь возможность видеть/изменять эти экземпляры. Другие пользователи не могут видеть экземпляры, созданные пользователем X.

Для этого я создал интерфейс IUserContextAware. Объекты, которые являются «контекстно-зависимыми пользователями», реализуют этот интерфейс.

При создании моей сессии-завод, я создал необходимые фильтры:

var currentUserFilterParametersType = new Dictionary<string, NHibernate.Type.IType> (1); 
currentUserFilterParametersType.Add (CurrentUserContextFilterParameter, NHibernateUtil.Guid); 
cfg.AddFilterDefinition (new FilterDefinition (CurrentUserContextFilter, 
                  "(:{0} = UserId or UserId is null)".FormatString (CurrentUserContextFilterParameter), 
                  currentUserFilterParametersType, 
                  false)); 

Когда это было сделано, мне нужно, чтобы определить дополнительные критерии фильтрации:

foreach(var mapping in cfg.ClassMappings) 
{ 
    if(typeof (IUserContextAware).IsAssignableFrom (mapping.MappedClass)) 
    { 
     // The filter should define the names of the columns that are used in the DB, rather then propertynames. 
     // Therefore, we need to have a look at the mapping information. 

     Property userProperty = mapping.GetProperty ("UserId"); 

     foreach(Column c in userProperty.ColumnIterator) 
     { 
      string filterExpression = ":{0} = {1}"; 

      // When the BelongsToUser field is not mandatory, NULL should be taken into consideration as well. 
      // (For instance: a PrestationGroup instance that is not User-bound (that can be used by any user), will have 
      // a NULL value in its BelongsToUser field). 
      if(c.IsNullable) 
      { 
       filterExpression = filterExpression + " or {1} is null"; 
      } 

      mapping.AddFilter (CurrentUserContextFilter, "(" + filterExpression.FormatString (CurrentUserContextFilterParameter, c.Name) + ")"); 
      break; 
    } 
} 

Теперь, когда я создаю экземпляр a ISession, я указываю, что необходимо использовать определенный перехватчик:

Этот перехватчик обеспечивает, чтобы параметр в фильтре был популятом изд:

internal class ContextAwareInterceptor : EmptyInterceptor 
    { 
     public override void SetSession(ISession session) 
     { 
      if(AppInstance.Current == null) 
      { 
       return; 
      } 

      // When a User is logged on, the CurrentUserContextFilter should be enabled. 
      if(AppInstance.Current.CurrentUser != null) 
      { 
       session.EnableFilter (AppInstance.CurrentUserContextFilter) 
              .SetParameter (AppInstance.CurrentUserContextFilterParameter, 
                  AppInstance.Current.CurrentUser.Id); 

      } 
     } 
} 
+0

Это звучит идеально для меня :) Спасибо! Эта статья помогла лучше использовать фильтры udnerstand: P http://nhforge.org/doc/nh/en/index.html#filters –

+0

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

Смежные вопросы