StackOverflowで this などの投稿を見ると、セキュリティのために、増分するIDを外部APIから非表示にする必要があるというコンセンサスがあるようです。
ただし、適切な実装を作成するのに問題があります。
here のように、ページの断片化につながり、以前にそれを行ったときに、DBにパフォーマンスの問題があったため(一部はIDが原因で)、GuidsをIDとして使用したくありません。
次のクラス構造を思いつきました。 int
IDがあり、外部識別用にGuid
があります。これに関する問題は、挿入と更新のためにdbへの過剰な呼び出しがあることを意味することです。
モデル:
public class Blog
{
public int BlogId { get; set; }
public Guid BlogGuid { get; set; } = Guid.NewGuid();
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public Guid PostGuid { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
DTO:
public class BlogDto
{
// No int id on dto
public string Url { get; set; }
public Guid BlogGuid { get; set; }
public List<PostDto> Posts { get; set; }
}
public class PostDto
{
// No int id on dto
public Guid PostGuid { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public BlogDto Blog { get; set; }
}
データの取得は問題ありません。前と同じように、取得してDTOに変換します。
更新または挿入を行う場合、データはすべてのオブジェクトのGUID IDだけで返されます。 this などのチュートリアルのように、エンティティを送り返すことはできません。
次に、元のデータ(Guid、インクルード付き)を取得する必要があります。次に、関連データ(Guidによって)を取得し、何をすべきか(挿入、削除、または変更された可能性がある)を調べる必要があります。それはすべて少し厄介で、データベースと不必要に雑談しているように感じます。
これはより安全=遅い場合に過ぎませんか、それともこの設計(私が思っているように)がなんらかの非効率的ですか?
クラスター化された主キーにGUIDを使用することについての リンクした投稿 でのアドバイスは7歳で、今日はほぼ間違いなく悪いアドバイスです。 参照する記事 参照SQL Server 7。
データベース内のすべての主キーにGUIDを使用し、JSONサービスにアクセスするURLにそれらのGUIDを公開します。これは、データベースの内部を外部に公開しないためです。この情報がない場合は、乱数を公開することもできます。その投稿で予測されているパフォーマンスの問題はありません。
GUIDには、主キーおよび外部キーとして非常に役立つ固有のプロパティがあります。 グローバルに一意であるため、結合するテーブルを気にすることなく、単一のJOINを使用できます。連続したIDとは異なり、隣接するGUID=を推測することは、GUIDを理想的な識別子にする最初の理由と同じ理由で、ほとんど不可能です。
増分IDの公開を防ぐ理想的な方法は? 代わりにGUIDを主キーとして使用します。GUIDは魔法のセキュリティ機能ではありませんが、どちらもintを難読化しません。残りのセキュリティ(SSL、ログイン、ロールベースのセキュリティ、Xサイトリクエストフォージェリからの強化など)が最初に堅実であることを確認し、GUIDを公開してそれらが何であるかを示しますとにかく表現するように設計されている(つまり、固有のリソース)は、問題が最も少なくなります。
StackOverflowでこのような投稿を見ると、セキュリティを確保するために、増分するIDを外部APIから非表示にする必要があるというコンセンサスがあるようです。
セキュリティについて話すときはいつでも、最初の質問は「私はどの脅威から保護しているのですか?」リンクする質問で概説されている脅威を見てみましょう。
要約すると、中心的なテーマは、攻撃者がシステムにどのようなIDがあるかをある程度知っている可能性があるということです。しかし、この情報はほとんどそれ自体では役に立たない。 IDは、攻撃者がそのIDを使用できるようにする別の脆弱性と組み合わせる必要があります。具体的には
サイトの使用状況の統計は別として、これらすべては単にIDを漏洩するよりもはるかに危険な脆弱性です。システムにこれらの他のギャップのあるセキュリティホールがないことを確認することは、使用するIDの種類を心配するよりもmuchより高い優先順位である必要があり、それらを接続すると、IDは役に立たない情報になります。
ここで、GUIDを使用してもここでは役に立たないことについて少し考えてみましょう。攻撃者は、GUIDを使用してIDにもアクセスできる可能性があります
GUIDは問題ありませんが、セキュリティが主な目的ではないため、一瞬、GUIDを盲目的に使用することがセキュリティ対策であると考えるべきではありません。それらはbestのあいまいさによるセキュリティの形式にあり、情報がプライベートに保持される必要がある場合、あいまいさはシステムが依存すべきものではありません。 IDの有用性を高める脆弱性の回避に焦点を当てます。
GUIDは、特に2つの異なる場所にデータを保存して後で結合する必要がある場合に、グローバルに一意のIDとして主に役立ちます。これが必要なければ、GUIDがなくても問題ないでしょう。 StackOverflowは、ユーザー、投稿、またはその他の何にも結局それらを使用しないため、自動的に脆弱性にさらされることはありません。それらを使用してサイトの使用量を隠す必要がある場合、それは合理的です。ただし、その情報を秘密に保つことはビジネス要件であり、アプリケーションの要件を設定する人と一緒に評価する必要があります。GUIDの使用はおそらくとにかくその問題を解決するための唯一のコンポーネント。 「より安全である」という漠然とした概念からではなく、アプリケーションの要件に基づいてGUIDを使用するかどうかを決定する必要があります。
GUIDの使用に対するアドバイスには日付が付けられているというロバートハーベイの声明に同意しません。クラスタ化インデックスでGUIDを使用する必要がある場合は、NewsequentialID()を使用することを推奨する クラスタ化インデックスのGUIDについて話しているより最近の投稿 、 SQL Server 2012のドキュメントを含む があります。そのアドバイスは今日でも関連があります。