7

プロパティを完全に無視するように Breeze に指示する .Net 属性はありますか?

プロパティを保護することは、Breeze から非表示にしてシリアル化を防ぐ 1 つの方法であることは知っていますが、プロパティを残しておきたい場合はどうすればよいでしょうpublicか?

4

2 に答える 2

15

EF によって生成されたメタデータがクライアントに対して 1 つのことを伝え、EF 自体に対して別のことを伝える、簡単で保守可能な方法を考案するのは困難です。

ただし、サーバー側モデル操作用の「実際の」DbContextと、厳密にクライアント メタデータ生成用の別のDbContextの 2 つのDbContextを用意する場合は、それを行うことができます。

メタデータの DbContext

思ったほど難しくありません。私はDocCodeでそのようなことを実験しました。NorthwindMetadataContextを継承するを作成しましたNorthwindContext。使用されていないCustomerID_OLDプロパティを非表示にします。

その DbContext 全体を次に示します。

パブリック クラス NorthwindMetadataContext : NorthwindContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(モデルビルダー);
        modelBuilder.Entity<Customer>().Ignore(t => t.CustomerID_OLD);
    }
}

あなたはその権利を読んだ!単一の EF Fluent API 命令を追加して、CustomerID_OLDプロパティを から非表示にしますNorthwindMetadataContext

それはまだCustomerタイプ上にあり、ベースにまだ認識されていますNorthwindContext。つまり、CustomerID_OLDを使用してクエリを実行するとプロパティが返されますが、 を使用してクエリを実行してNorthwindContextもプロパティは返されませんNorthwindMetadataContext

もちろんNorthwindMetadataContext、Breeze クライアントのメタデータを生成するためにのみ使用します。すべてのサーバー ロジックは引き続き「実際の」ベースを使用します。NorthwindContext

プロパティのNorthwindRepository実装方法を変更することで、それが起こることを確認します。Metadata

公開文字列メタデータ
{
    得る
    {
        var metaContextProvider = new EFContextProvider<NorthwindMetadataContext>();
        metaContextProvider.Metadata(); を返します。
    }
}

の他のすべてのメンバーは、「実際の」DbContextにEFContextProviderNorthwindRepositoryを使用します。

プライベート読み取り専用 EFContextProvider<NorthwindContext>
    _contextProvider = new EFContextProvider<NorthwindContext>();

これは魅力のように機能します。クライアントが知る限り、そのCustomerID_OLD物件は存在しません。

隠されたデータをネットワークから遠ざけるようにしてください

プロパティを Breeze クライアントから非表示にしましたが、プロパティはサーバー側のエンティティ タイプのままであり、クエリと保存操作に「実際の」DbContext を使用するため、CustomerID_OLDプロパティがクエリ内のネットワークを通過することを確認できます。結果ペイロード。

これが起こらないようにするために、JSON.NET シリアライザー[JsonIgnore]属性をCustomer.CustomerID_OLDモデルのプロパティに追加できます (モデルを JSON.NET シリアライゼーション属性で汚染したくない場合は、他の JSON.NET 構成オプションを使用します)。

再度実行すると、CustomerID_OLDシリアライズされなくなります。プロパティは、CustomerID_OLDサーバー上のモデルでは引き続きアクセスできますが、クライアントからは完全に見えなくなります。

注意してください

メタデータに隠されているプロパティは、Breeze クライアントからは隠されていますが、世界からは隠されていません。SERVER-SIDE TYPE でそのプロパティを使用できるようにするため、完全な型をシリアル化するときに非表示にした場合でも、悪意のあるクライアント (Breeze クライアントではない) が射影を使用してそのデータを取得できます。

CustomerID_OLD次のクエリ URL は、オブジェクト全体をクエリした場合に表示されないを含む投影データを返しCustomerます。

http://localhost:47595/breeze/Northwind/Customers?$filter=startswith(CompanyName,'C') eq true&$select=CustomerID_OLD,CompanyName

結果の一部を次に示します。

    {
        "$id": "1",
        "$type": "_IB_em9q7XTURqKf5bmIrAQD0bJ6f_po[[System.String, mscorlib],[System.String, mscorlib]], _IB_em9q7XTURqKf5bmIrAQD0bJ6f_po_IdeaBlade",
        "CustomerID_OLD": "CACTU",
        "CompanyName": "Cactus Comidas para llevar"
    }、

おそらくもっと深刻なことに、POST は「SaveChanges」リクエストのペイロードでその非表示のプロパティに更新できます。

機密データの場合と同様に、すべての保存要求を調べてOriginalValues、コレクションで識別されたすべての変更されたプロパティ値をユーザーが保存することを許可されていることを確認する必要があります。

セキュリティ上の懸念がある場合は、許可されていないクライアントに公開してはならないデータを運ぶ型にDTO を使用する方がはるかに安全だと思います。すべてのタイプの DTO が好きというわけではありません。それは生産性を台無しにする可能性のあるやり過ぎです。しかし、重要な機密性要件を持つエンティティ タイプについては、私はそれらを気に入っています。

サンプルコード

この例を公開された DocCode に保持するか、それとも私用に保管するかはまだ決めていません。クールなトリックです。

私の懸念は、この手法が機密データを隠すための安全な方法であると人々が考えるかもしれないということです。隠しておきたいデータを隠すのには問題ありません。ただし、ネットワークから切り離しておく必要がある場合は、DTO を使用することをお勧めします。

私が説明したことが、具体例なしで先に進むのに十分明確であるかどうか教えてください.

于 2013-05-01T07:33:21.493 に答える
6

Json.Net シリアライザー ( Breeze.WebApi のデフォルト) を使用している場合は、こちらで説明されている JsonIgnoreAttribute を使用できます。

于 2013-04-30T05:31:09.927 に答える