2011-08-10 4 views
2

Fluent NHibernate(1.2)を使用しており、カラムレベルの暗号化の実装に取り​​組んでいます。私は、ドメインモデルがネイティブのクリアテキストデータ型(単純な文字列、ints、DateTimesなど)を持つことができるように、暗号化を扱うカスタムタイプを持っていて、すべての暗号化/復号化作業が裏で行われています。Fluent NHibernate:コンポーネントを介してマッピングされたプロパティのすべてのメンバーに属性を適用する

属性を使用して暗号化する各ドメインモデルのプロパティを指定し、これらのプロパティのカスタムタイプを指定するためにコンベンションを使用して、ドメインモデルがカスタムタイプについての素晴らしいPOCOであるようにしたいとします。

public class EncryptedAttribute : Attribute {} 

public class UserRecord { 
    public virtual Guid Id { get; set; } 
    public virtual string Username { get; set; } 
    [Encrypted] 
    public virtual string EmailAddress { get; set; } 
    [Encrypted] 
    public virtual DateTime DateOfBirth { get; set; } 
    [Encrypted] 
    public virtual PersonName LegalName { get; set; } 
    // etc. 
} 

public class PersonName { 
    public virtual string Given { get; set; } 
    public virtual string Middle { get; set; } 
    public virtual string Family { get; set; } 
} 

public class EncryptedColumnConvention 
    : AttributePropertyConvention<EncryptedAttribute> { 
    protected override void Apply(
    EncryptedAttribute attribute, IPropertyInstance instance) 
    { 
    var dbType = typeof(EncryptedColumnType<>).MakeGenericType(domainType); 
    instance.CustomType(dbType); 
    } 
} 

public class UserRecordMap : ClassMap<UserRecord> { 
    public UserRecordMap() { 
    Id(o => o.Id); 
    Map(o => o.Username); 
    Map(o => o.EmailAddress); 
    Map(o => o.DateOfBirth); 
    Component(o => o.LegalName).ColumnPrefix("LegalName"); 
    // etc. 
    } 
} 

public class PersonNameMap : ComponentMap<PersonName> // etc. 

上記のとおり、私はこれをAttributePropertyConventionと結びつけようとしています。これは、単純なプロパティ(例: EmailAddressはEncryptedColumnTypeのカスタムタイプを取得します。

しかし、コンポーネント経由でマッピングされた複合タイプ(例:LegalName)のプロパティでは機能しません。私が望むのは、私が[Encrypted]でそれを飾ったので、LegalNameのすべてのプロパティを暗号化することです。言い換えれば、私は、UserRecordのdbテーブルに、指定された、中間の、そして家族の3つの暗号化された 名前フィールドが必要です。

AttributePropertyConventionは、LegalNameまたはそのメンバープロパティにまったく適用されないようです。おそらく私はこのケースを扱うために別の種類の条約を使用する必要がありますか?

私は、UserRecord内の[LegalName]プロパティを飾るのではなく、[Encrypted]を使ってPersonName内の個々のプロパティを飾ることができます。私はこれをテストし、正常に動作します。必要に応じて私はこのアプローチに落ちることができますが、代わりに上記のアプローチの概要を得ることに興味を持っています。

答えて

0

フォローアップでは、私が記述したものを直接実装する方法が見つかりませんでした。属性がC#でどのように機能するかに基づいて、そのようなことを実装することは困難または不可能であることがわかりました。

代わりに、PersonNameクラスの各プロパティに[Encrypted]属性を追加し、結果のデータベーステーブルのこれらのPersonName列を常に暗号化させました。将来、PersonNameを別のエンティティの暗号化されていない「コンポーネント」としてマップする必要がある場合は、がマッピングされたすべての列/コンポーネントに対して暗号化を無効にする属性で非暗号化クラスを飾ることができますそのクラスのプロパティ/コンポーネントマッピング内に見つかった属性[Encrypted]

関連する問題