2011-02-07 3 views
3

NHibernate를 사용하여 권한을 구현하려고하는데 선택 쿼리가있을 때마다 반환 유형이 무엇인지 확인하고 보안 인 에이블 유형 (예 : 송장)이 필요한 경우 특정 레코드 만 검색하는 것을 제한하려면 ICriteria 개체에 제한을 추가합니다 (사용자가 모두 읽었거나 자신의 권한을 읽은 경우에 따라 다름). NHibernate PreSelect?

나는

NHibernater.Event.IPreUpdateEventListener 
NHibernater.Event.IPreInsertEventListener 

하지만 데이터베이스가 쿼리 후 불행하게도 IPreLoadEventListener를 호출하여 삽입 및 업데이트에 대한 권한이 종류를 구현하기 위해 관리 및 필터링이에 로컬로 수행됩니다 따라서 그것은 낭비 컴퓨터가 아닌 데이터베이스를 사용합니다.

NHibernate가 쿼리가 실행되기 전에 호출되는 일종의 이벤트를 제공하는지 아는 사람 있습니까?

답변

2

당신은 그것은 당신이해야 할 노력하고 정확하게 수행 Rhino.Security을 확인, 사용할 수 있다면. 당신이 그것을 사용할 수 없다하더라도, 당신은이 문제의 그의 구현을 볼 수 있습니다.

+0

나는 그것을 사용하는 방법을 알아 내려고하지만, 진짜 힘든 시간을 보내고 있습니다. (바로 지금 Frederik의 솔루션을 구현할 생각입니다. –

+0

@ LnDCobra 예, 그것에 대한 많은 문서가 없습니다. – Vadim

2

필터를 사용하여이를 수행 할 수 없습니까?

here

내가 내 프로젝트의 인터셉터와 함께이를 사용했습니다 찾을 수 있습니다

더 많은 정보 : I는 각 사용자의 인스턴스를 만들 수있는 몇 가지 요소를 가지고

을하지만 사용자 만 사람을 해당 인스턴스를보고 수정할 수 있어야합니다. 다른 사용자는 사용자 X가 만든 인스턴스를 볼 수 없습니다.

이렇게하려면 인터페이스 IUserContextAware을 만들었습니다. '사용자 컨텍스트 인식'인 엔티티는이 인터페이스를 구현합니다. 내가 인스턴스화 할 때마다, 지금

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; 
    } 
} 

이 완료되었을 때, 나는 추가 필터 기준을 정의하는 데 필요한

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)); 

:

내 세션 공장을 건설

, 내가 필요한 필터를 생성 ISession이라면 특정 인터셉터를 사용해야한다고 지정합니다 :

이 인터셉터는 필터의 매개 변수가 populat인지 확인합니다 에드 :

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

이것은 나에게 완벽하게 들립니다 :) 감사합니다! 이 기사는 필터를 더 잘 이해할 수 있도록 도와주었습니다 : P http://nhforge.org/doc/nh/en/index.html#filters –

+0

실제로, 나는 이것이 작동하지 않을 것임을 깨달았습니다. 필터는 모든 다른 엔티티 (그리고 심지어 시간이 지남에 따라 동일한 엔티티)에 대한 모든 시간을 바꿀 것입니다. –