テーブルセキュリティ

Power Portals Proは、ユーザーが触れられるテーブル、そのテーブルのどの列を表示・変更できるか、そしてどの行が戻ってくるかという3レベルでデータを保護します。これら3つすべては、テーブルごとに1つの登録で決定されます。その登録をAddTableAccessで説明してください— それはテーブルを付与する方法であり、プロジェクトテンプレートが登録するすべてのテーブルで何を使うかです。ルールが説明できない場合は、同じ3つの回答をITablePermissionProviderクラスとして書くこともできます。両者とも同じものを生成し、同じ方法で構成します。いずれかが許可するまでは何も付与されません:登録対象外のテーブルはアクセス不可であり、これが失敗クローズドデフォルトです。

ヒント

これを白紙のページから書く必要はありません。 生成されたプロジェクトには secure-a-table スキルがあります。コーディングエージェントにテーブルの保護を依頼し、どのテーブル、誰のため、どの行、どの操作、どの列を解析し、登録を書き、Power Portals Pro MCPサーバーを通じてDataverseで対応する変更を行います。アクセスがロールバウンドの場合はポータルロールを作成し、回答が示唆する権限をアプリケーションユーザーに付与します。その後、 check_setup ページがバインドされているテーブルでアクセス権が付与されないものや、カラムセキュリティをオプトアウトする登録を報告します。 MCPサーバー→はじめをご参照ください。

みんな、あるいは一部の人だけ

すべての登録は誰のためのものかを示しており、答えは二つあります。ポータルに対して登録すると、 コードネー ム(全員、またはサインインしているすべてのユーザー)に適用されます。 AddPortalRole に登録すると、その役割の保持者に適用されます。これはDataverseで管理者が行う データ 上の決定です。アクセス自体は両者で同じように説明されます。

登録 適用対象 誰がそれを手に入れるかを変えるために
AddTableAccess("account", t => t.ForSignedInUsers()…) 観客がカバーするすべての人、あらゆるリクエストに応じて コードを編集して再デプロイしてください
AddPortalRole("Credit Manager", role => role.WithTableAccess("account", …)) そのポータル役割を持つ連絡先だけで、他の誰もいない Dataverseで役割の割り当てまたは解除 — デプロイメントなし

各ポータル全体のオーディエンスごとにテーブルを一度登録できます — ForEveryone() 誰でも到達できるもの、サインイン ForSignedInUsers() 追加されるもの — そして2つを合計します。訪問者は最初のものを得ます。サインインしたユーザーは両方を得て、それぞれの操作はそれを付与する登録の行に限定されます。以下の2つの登録があれば、全員がすべての記事を読み、サインインした著者は記事を書き、自分の記事を編集することもできます。

ロールは加算しますが、決して減算しません。 ユーザーのアクセスはポータル全体の登録と、その人が持つすべてのロールの統合です。つまり、ポータル全体の登録は全員が立つ床であり、ロールはそれを上げるだけです。ロールはポータル全体の登録で付与された列や行を取り消すことはできません。ほとんどの人から何かを差し止めたい場合は、ポータル全体ではなくロールで付与してください。(すべてのグループが同意する必要がある場合は SecurityOptions.Roles.CompositionBehavior を Restrictive に設定してください。)

つまり、 そのような すべてのユーザーがアクセス権を持つべきなら、ポータルに対して登録してください。もし一部のユーザーだけがアクセス権を持つなら――そしてどの人が誰かはリリースなしで答えが変わる質問ですが――それをロールに入れるのです。ロール登録は、誰かがその名前のポータルロールレコードを作成し割り当てるまで何も付与しません。だからこそ、新しいプロジェクトに無害に置いてもいいのです。

テーブルのアクセスの記述

ほとんどのテーブルは同じルールを求めています:テーブルが誰のためか、どの行に到達するか、何をしてよいか、どの列を見るか。 AddTableAccess 4つすべてを1つの登録で表示し、通常の ITablePermissionProvider を生成します。下流の誰も違いを知りません。購入できるのは、合意しなければならない3つの決定(フィルター、作成、書き込み可能な列)が3回ではなく1回行われることです。

オーディエンス、行の範囲、 Allow(…) はすべて必要です。しかし、どれもデフォルトは存在しません。なぜなら、すべての妥当なデフォルトは何かを省略してデータを公開する方法であり、登録が間違えれば起動時に失敗し、本番環境では失敗しないからです。

ロウスコープ

スコープはテーブルのすべてのクエリ—グリッド、ルックアップ、サブグリッド、チャート、そして保存や削除前のフェッチ—をフィルタリングします。名前付きスコープはポータルが常に必要とする形状をカバーしています:

どの列が 範囲 オンクリエイト
すべての列 AllRows() 何も設定されていません
ユーザー自身の記録 RowsOwnedByContact("customerid") 検索はそれらに設定されています
同じアカウントで同僚の記録も RowsOfTheirAccount("customerid") 検索は相手のアカウントに設定されています
親にぶら下がる記録は、彼らが届く範囲に RowsViaParent("salesorderid", "salesorder", p => …) 何も決まっていません — 親自身のアクセスが決めます
複数の形で彼らを指し示す記録 RowsMatchingAny(r => r.RowsOwnedByContact("customerid"), r => r.RowsOfTheirAccount("customerid")) 最初に記載された所有範囲のセット
彼ら自身の接触列 OwnRecordOnly() 作成しない

所有権スコープは、権限チェックの後にレコードが作成される際にカラム自体を設定します。ユーザーは書き込み権限や、指すテーブルに付加する必要がなく、値はリクエストではなくセッションから来られ、後で変更されるセーブは拒否されます。これが、誰かが作成したレコードを自分が対象とするフィルター内に保持する仕組みです。所有カラムが行をフィルタリングするカラムでない場合、プラグインがすでに設定している場合はWithoutStamping()OwnedBy('column')を使いましょう。

読むときと変化の違い

1つのスコープは、特に指示がない限りすべての操作に対応します。 RowsForWriting 、ユーザーが変更できる行を絞り込むが、表示される行は絞り込まれません。「すべての人がすべての連絡先を読み、それぞれ自分のものだけを編集する」という区別だけで、それ以外は何もありません。 RowsForDeleting はさらに削除を狭めます。なぜなら、レコードを修正することを許すことは、それを破棄することを許されるのとは異なるからです。各記録はその上の記録に戻るため、区別されない登録は区別されないことを意味します。クリエイトは影響を受けません。まだフィルタリングすべき行は存在しません。

名前付きのスコープが合わないとき

RowsMatching 登録を離れずに自分でフィルターを取る。FetchXML — <filter> 要素や <fetch> 全体で、そのフィルターと結合がコピーされ、サインインした連絡先には {currentUserId} が付けられる — あるいはリクエストごとに実行され、サービスの応答から作成されたFetchXMLか、自ら作成したフィルターを返すコールバックを与える。どちらもプロバイダーと同じ TableQueryContext を受け取るため、誰が質問しているのか、行が読み取られる、更新されるのか、削除されるのかが分かる。何も返さなければ行は得られない: TableQueryFilter.AllRows 、行を「すべての行」と言う。

ロールのアクセスの記述

内部 AddPortalRole 役割はオーディエンスであり、登録は他の名前を挙げません。役割は加算し、決して減らしません。ユーザーのアクセスはポータル全体の登録と、彼らが持つすべての役割を統合して含みます。ポータルの役割自体――それが何であるか、どのように割り当てられ、どのように構成されるか――は次のセクションです。

注記

プロバイダークラスは記述では表現できないものを表現する手段であり、構成は同一で、 AddTablePermissionProvider<T> と WithPermissions<T> は変更されません。生成されたプロジェクトはもはやプロバイダークラスを出荷しません。登録したすべてのテーブルが記述されており、 contact やクレジットマネージャーの役割も含まれます。

ポータルの役割

ポータルの役割はポータルを保護するための推奨される方法です。権限提供者を管理者がDataverse内の連絡先に割り当てる名前に紐づけ、提供者はその役割を持つ人にのみ適用されます。そして、その権限を持つ人はコードではなくデータです。比較すると、Program.csに直接登録されたプロバイダーはすべてのユーザーに適用されます。

この分割は意図的なものです。 Dataverseは名前と割り当てを所有しており、管理者がモデル駆動型アプリで管理します。あなたのコードが各名前 の意味を所有します。誰かのアクセスを付与または取り消すことはデータ変更にあたります。再構築も再デプロイもなしです。

1. 役割を作成し、割り当てる

ポータル ロール レコードを作成し、それを持つべき連絡先に割り当てます。ロールレコードには名前と説明しか含まれず、Dataverseには権限データが存在しません。

2. 役割を提供者に縛り付ける

役割レコードの名前と一致し、何が付与されるかを記載してください。プロバイダーの種類はあなたのために登録されているので、自分で登録する必要はありません。

最後の点が重要です:ロールの提供者もAddTablePermissionProvider<T>()に登録してはいけません。それはグローバルセットに含まれ、全員に付与され、役割を静かに無効にします。すべてのユーザーに本当に適用されるルールには、AddTablePermissionProvider<T>()を取っておきましょう。

役割の組み合わせ

ユーザーの権限は、グローバルに登録されたプロバイダーと彼らが持つ各役割から得られ、これらのグループはこのようにまとめられます:

ヒント

加法的合成では 何も否定されません — 何かはどのグループも開かない間だけ閉じたままです。グローバルに登録されたプロバイダーは、すべてのユーザーに適用されるルールの正しい居場所です。なぜなら、常にフォールドに含まれているからです。しかし、それは拒否権ではありません。操作を付与するか、カラムに名前を付ける役割が再開します。ユーザーが持つ役割を閉じたままにするには、全く役割に付与しないか、すべてのグループが合意しなければならない SecurityOptions.Roles.CompositionBehavior 「 Restrictive」に設定するのが正しいです。

ページ上の役割とナビゲーション

ロール名は ASP.NET 標準的なロールクレームとしてブラウザに届くため、ページ認証や条件付きUIは追加処理なしで機能します。

Reactスタックは同じ名前を auth.user.rolesから読み込み、ゲート <AuthorizedView roles="Dealer"> コンテンツも同じ方法で処理します。内部(システムユーザー)サインインはここでDataverseのセキュリティロール名を持ち、両方のユーザーを一つのチェックでカバーできます。

適切な役割の承認

ポータルロールとDataverseセキュリティロールは名前を共有し、 [Authorize(Roles = "…")] 区別できません。これは両方を含む型なしロールの主張に一致します。2つの属性がより狭い問いを投げかけます。

ロール名は逐語的に使えます。コンマ、コロン、引用符はすべて問題ありません。なぜなら名前はリストから解析されないためです。2つの属性をスタックするには、スタックされた[Authorize]属性が常にそうであるように両方が必要です。1つの属性に2つの名前をリストアップするには、どちらかが必要です。同じチェックはUser.IsInPortalRole("Dealer")やUser.IsInSecurityRole("Sales Manager")と同様にコード内で利用可能です。

Blazorマークアップでも同じ区別があります。 <AuthorizeView Roles="…"> は型なしの役割主張を読み取るため、plain属性と同じ曖昧さを持ちます; <PortalRoleView> 一種類を求めます。単一の名前に対して PortalRole / SecurityRole 、または複数に対して PortalRoles / SecurityRoles を与えてください。これはカンマで区切られた文字列ではなくコレクションです。なぜならDataverseの名前は通常コンマを含むからです:

Reactの <AuthorizedView> は、既存の roles ゲートと並んで同じ2つのゲートを受け入れます。ゲートに複数の名前を与えることは、いずれの名前でも意味します。2つのゲートを指定する場合は、両方を意味します。それらの背後にある述語 — hasPortalRole、 hasSecurityRole、 hasRole — は命令チェックのためにエクスポートされます:

ベストプラクティスは、ソースからフィルタリングすること

保護対象が本当に管理的なものであれば、これらの権限を活用しましょう。ポータルロールの作成は、Dataverseのセキュリティロールを付与されるよりも意図的に低いハードルなので、どちらかを承認するチェックは、管理者がDataverseの役割を守っていたアクセス権をポータルロールに名前付けすることで与えられるようにします。

注記

ロールは無料ではありません。ユーザーが保持する各ロールは認証クッキーに2回書き込みされます。1回は標準的なロールクレームとして使われ [Authorize(Roles)] 、もう1回は上記のチェックを可能にする種類ごとのクレームとして、1ロールあたり約160バイトです。ユーザーあたり約15の役割は1つのクッキーに収まります。それ以降はクッキーがチャンクに分割され、最初に動くのは通常リバースプロキシのヘッダー制限で、役割に関する記述ではなく不透明な400の表示が出ます。狭い役割よりもいくつかの広範な役割を好む。

新規ユーザーにスタートロールを与える

新しいアカウントが最初に持つべき役割と、サインアウトした訪問者に適用される役割を挙げてください:

またはリリースなしでDataverse上で決定することもできます。 Portal Role Configuration tableは役割と割り当てモードをペアリングし、管理者はモデル駆動型アプリから誰が何を受け取るかを変更できます:

役割がその人(メールドメイン、サインインしたプロバイダー、招待など)に依存する場合は、代わりに IPortalRoleAssignmentProvider を登録してください。登録済みのすべてのプロバイダーに相談されるため、あなたの役割は設定済みリストに加えられ、置き換えられません。いずれにせよ、割り当てはアカウント作成時に一度だけ実行されます。サインイン時に再適用されることはなく、管理者が削除した役割はそのまま削除されます。

注記

ユーザーは新たに割り当てられたロールをサインアウトして再ログインすることで取得します。サインインするとロールが再読みされます。ロール割り当てはユーザーごとに24時間キャッシュされるため、すでにサインインしている人に変更を適用するには、サイト管理エリアから Portal Roles キャッシュをクリアしてください。セッションが次に更新された際に10分以内にキャッシュされ、削除されたロールは機能しなくなります。ちょうど追加されたロールが始まると同時に。Portal Role Configuration テーブルは15分間別にキャッシュされるため、そこに追加された行は自動的に次の登録に到達します — 「PortalRoleConfiguration」キャッシュをクリアして即時登録にします。設定行を非アクティブにすると役割の割り当てが停止され、役割を無効化すると同様に取り消されます。

代わりにプロバイダーを書く

説明だけでは意味が伝わらないクラスに手を伸ばしましょう。例えば、コードだけが知っているルールや、レコードを操作しなければならないルールなどです。 ITablePermissionProvider 、どの登録も同じ結果になります。1つのプロバイダーが1つのテーブルを管理し、ユーザーがそのテーブルで何をできるか、どの列を読み書きできるか、そして下のクエリフィルターを通じてどの行が見えるかを把握します。説明された登録と書き込まれた登録は同じ構成なので、ポータルは両方を使い、一方でテーブルを付与し、もう一方で拡大できます。

インターフェースには1人の必須メンバーがいます。 GetPermissionsAsync はユーザーのID、ポータルロール、Dataverseセキュリティロールを含む UserInfo を受け取り、そのユーザーが受け取るすべての情報を説明した返 TablePermissions を返します。

プロバイダーの登録

このように登録されたプロバイダーは、サインインしているかどうかに関わらずすべてのユーザーに適用されます:

また、これは全員から何かを 奪 う唯一の方法でもあります。役割はデフォルトで加算的に合成されるため、役割はアクセスを追加しても削除はできません。ポータル全体の制限は、グローバルに登録されたプロバイダーに適用されるべきであり、それも常にその一部です。

運用

TablePermissions.Operations は TableSecurityPermission フラグの値 — Read、 Create、 Write、 Delete、 Append 、 AppendToです。知っておくべきことが2つあります。

注記

「読み込み後に各行を検査する」というフックは意図的にありません。その方法でフィルタリングするとページングが壊れます。50ページ分のページはより少なくなります。合計カウントが誤りになり、Dataverseに行を回収して捨てる行を請求します。代わりにクエリをスコープ化することでページングが続き、計算自体が正しくなります。

ベストプラクティスは、ソースからフィルタリングすること

クエリ内のスコープデータであって、クエリの後ではなく。フレームワークは、フェッチされた各行を検査するフックを意図的に提供していません。この方法でフィルタリングするとページングが壊れ(50ページが短くなり)、合計カウントが誤り、Dataverseに行の取得を依頼して破棄します。 GetQueryFilterAsync クエリ実行前に条件を追加するため、ページングやカウントは構成上正しく保たれ、ユーザーが見られない行は一度も取得されません。

行レベルのセキュリティ

GetQueryFilterAsync フレームワークがDataverseを実行する 前に 質問に追加するフィルターを返すため、ユーザーが見られない行は決して取得されません。このクエリは、ポータルがテーブルに対して発行するすべてのクエリ(グリッド、ルックアップ、サブグリッド、チャート、シングルレコードロード)に適用され、両方のセキュリティモデルで動作するため、Dataverseネイティブのセキュリティがオペレーションゲートを回避しても有効に機能します。

context.CreateFilter()でフィルターを作成し返します。nullを返すということは、行の制限がありません。コンテキストには現在のユーザーEntityReference、彼らが持つ役割、そして行が使われる予定の内容が含まれます。条件は、他の場所で使われているのと同じFetchXMLBuilderAPIを通じて追加されます: FetchXMLBuilder

このプロバイダーは3つの列 contact を付与し、すべての連絡先クエリをサインインしたユーザー自身のレコードにスコープします。

読み込み、更新、削除

TableQueryContext.Operation なぜ行が取られるのかが説明されているので、プロバイダーごとに異なるスコープを割り当てることができます:

複数のフィルターがどのように組み合わさるか

テーブルは複数のプロバイダーを含みます — グローバルに登録されたプロバイダーと、ユーザーが持つ各役割から1つ。フレームワークはフィルターの組み方を決定するため、プロバイダーは他のフィルターが何をしたかを知る必要はありません。

注記

行は閉じて失敗します。列のように、 null を返すプロバイダーや条件のないフィルターは行を 割り当てず、 グループ内ではグループを空にします。すべての行は TableQueryFilter.AllRows で求められます。そこに非対称性があります。すべての行の和集合はすべての行であり、テーブルに答えるグループが AllRows すると、他のロールがスコープを慎重に設定しても、テーブルはフィルターなしで戻ってきます。これが加法合成の意味ですが、役割のフィルターが無視されているように見える唯一の方法です。

関連テーブルを通じたフィルタリング

AddLink テーブルを結合し、フィルターがカラムをテストできるようにします。テストをリンクではなくフィルター内に配置してください。フレームワークが外側への結合を緩めてもフィルター内の条件は動作し続け、リンク上の条件は以下の通りに機能しません。

注記

上記の結合は多くの行に 及 ぶため、Dataverseはメンバーシップごとに1回だけアカウントを返します。行を繰り返すグリッドと合計でカウントします。フレームワークはその形状を認識し、クエリ distinctにマークし、テーブルのプライマリキーを投影して、重複解除で結合が追加された行だけを削除できます。代わりに 上 に伸びて関連するテーブルのプライマリキーに結合するジョインは、最大でも1行だけ一致し、そのままそのままになります。いずれにせよ、フィルターだけを書き、それ以外は書かず、ジョインは無料ではなく、テーブル自身の列にフラットな条件として表現できるルールの方が安価な形状であることを知っておく価値があります。

ヒント

テーブルごとに異なるスコープが必要な場合でも、 1つの プロバイダーを書いて context.User.PortalRoles にブランチをすることはできますが、もはやその必要はありません。2つのロールはそれぞれ独自のプロバイダーを持ち、フレームワークのユニオンがフィルターを割り当ててくれます。

新記録の所有者は誰か

行フィルターはスコープ、読み取り、更新、削除を行いますが、作成はフィルターすべき行を持ちません。したがって、「私が所有する行」にスコープが設定されたテーブルでも、ユーザーは他の誰かの所有する行や、誰も所有していない行を作成でき、作成者はそれを見ることができません。レコードの所有者を示す列を宣言すると、フレームワークがそれを設定します:

同じ列に行フィルターを組み合わせて、ユーザーが作成するレコードが見えるレコードになります。単なる作成連絡先(例えばクリエイターのアカウント)でない所有者権については、 ITableRecordOwnershipProvider を実装して AddTableRecordOwnershipProvider<T>()に登録してください。代わりに ITableRecordInterceptor で所有者を設定しないでください。インターセプターは許可チェックの前に動作するため、設定したものはユーザー自身の書き込みと判断されます。

フレームワークはそのテーブルの作成ごとに権限チェックの後に呼び出し、 Columns 内の各列を返すものに設定します。リクエストが送ったものはすべて破棄し、その後の更新で変更を拒否します。これは OwnedByと同じです。設定内容に一致する行フィルターを組み合わせ、記録をファイルできる相手に設定します。ここでは RowsMatchingAny(r => r.RowsOfTheirAccount("customerid"), r => r.RowsOwnedByContact("customerid"))、 WithoutStamping() で登録がこの提供者に列を残します。1つの列を異なる設定で設定した2人はセーブに失敗します。

カラムレベルのセキュリティ

カラムのセキュリティは オプトイン制です。プロバイダーは公開したいカラムを付与し、それ以外(来年誰かがテーブルに追加するカラムも含めて)は名前が指定されるまで保留されます。レコードのプライマリIDは常に読み取れます。フレームワークが特定できないレコードは誰にとっても役に立たないからです。

読み取りと書き込みは独立した集合です。列は読み取れるが書き込み不可(「クレジット限度額を表示し、変更させない」ケース)または書き込み可能だが読み取れない場合があります。 Reading、 Writing 、 ReadingAndWritingで名前を付けるか、 ReadingAllColumns / WritingAllColumnsで次元を完全に除外することもできます。

注記

ReadingAllColumns() 意図的にタイプしなければならないものです。後からテーブルに追加されるものに対しては無効になりますが、これはテーブルが本当に公開されている場合に限り正しい取引です。したがって、フレームワークはあなたの代わりにそれを仮定しません。

書き込みはレコード の作成 と 変更 の際にも異なる場合があります。 Writing は両方をカバーしています。 WritingOnCreate ユーザーがレコードを作成する際に列を設定し、それ以降は読み取り専用にできます。これはケースの優先度であり、ログ時に選択されます。 WritingOnUpdate は逆で、既存のレコードでは変更可能で、開始時に設定可能ではありません。どちらもカラムを読みやすくし、 Writingと同様に、自分のプロバイダーに対して TablePermissions に存在します。Dataverse自身のフィールドセキュリティが付与する別個の権限の作成と更新権限をミラーリングしています:

フレームワークは、データがサーバー境界を通過するすべての経路で結果を強制します:

注記

テーブルのプライマリID列は、読み取りセットが何と書かれていても決して保留されません。idはデータではなくアイデンティティであり、呼び出し者がレコードにアクセスするために使ったURL内にあります。行キー、編集リンク、サブグリッド関係、削除はすべてIDなしでは解体されます。ページに必要な列の名前を付けてIDを忘れる許可リストは、ポータルを壊し、何も保護しないでしょう。

コンポーネントの挙動

フレームワークのコンポーネントは単独で列権限を尊重しており、何かを配線する必要はありません。ユーザーが 書 いてはいけない列は表示専用で表示され、表示される場所は無効化されます。すべてのエディタは共有の読み取り専用解像度を通じてそれを拾い、グリッドはセルにインラインエディタを割り当てないため、プレーン表示テキストに戻されます。消費者提供の readOnly="false" はそれを上書きしません — どちらにせよサーバーはセーブを拒否します。

ユーザーが 読 んではいけないマスキングされた列は、両方のスタックでエディタではなく、 <ColumnDisplayValue> を通じてレンダリングされます。これは単なる細かい点ではありません。マスクされたカラムは何の値もなく、マスクだけが フォーマットされた 値なので、それに割り当てられたエディタは空欄に表示されます。 ColumnDisplayValue はフォーマット済みの値を読み取り、カラムの型に関係なくプレースホルダーを表示します。省略によって保留されたカラムは、レコードに表示されず、テーブルのメタデータにも記載されません。

クライアントが受け取るもの

カラム権限はColumnPermissionsマップとして提供されます。これはアクセスが狭まるカラムに対してColumnSecurityPermissionフラグペアへのカラム名であり、Writeは既存のレコード上でカラムを変更することを意味します。欠如したものは完全なアクセス権を持つため、制限のないテーブルは何も含まれません。単独で取得したレコードはマップを保持します。同時に取得したレコードは1つのマップを共有し、レスポンス時に一度送信されます。権限は行ではなくユーザーとテーブルに属するため、両方のスタックのクライアントが各レコードに戻すため、記録の権限の読み取りはどちらの場合も同じです。グリッド応答もまた、列ごとに報告ResolvedColumn.Permissions。作成中のレコードにはまだ独自のマップがないため、テーブル権限エンドポイントもNewRecordColumnPermissionsを返します。これは作成時に設定されるものによって判断される同じ形状で、両方のスタックのRecordContextが新しいレコードに割り当てます。省略された列は意図的にすべてのマップに欠けています。省略は存在しないため、回答に列名が現れず、名前を付けるとその意味が元に戻ってしまいます。Blazorのrecord.CanReadColumn(column) / record.CanWriteColumn(column)、またはReactの@powerportalspro/coreの対応するcanReadColumn / canWriteColumn helperで自分で読んでみてください。

省略またはマスキング

デフォルトでは、保留された列は マスクされます。レコードはその値を持ち、 SecurityOptions.WithheldColumnMask (デフォルトで***** )がフォーマット値なので、フォームやグリッドでもフィールドを表示し、値が空白ではなく保留されていることを明確に示します。マスキングは値があるかどうかに関わらず同じなので、それも隠します。 SecurityOptions.WithheldColumnBehavior を Omit に設定すると、クエリがその列を要求したことがなかったかのようにレコードからその列を完全に削除し、応答からその列の存在を示さないようにします。これは、列の存在自体が機密の場合に正しい選択です。列を保留すると、再公開する列も差し止められます。例えば、検索の名称の伴いやマネー列の基準通貨の双子などです。つまり、ある列の名前を付けた拒否リストが別の列を回避できないようにします。単一のテーブルでサイト全体の選択を上書きできます TableColumnPermissions.WithheldColumnBehavior。

注記

マスクされたカラムと書き込み拒否を組み合わせます。マスクされたカラムはレコードに値がないため、ロードされたレコード全体を投稿した呼び出し者は何も送りません。しかしフレームワークはセイブペイロードをフェイスバリューで受け取るため、マスクを含むカラムを設定するリクエストは、そのカラムが書き換えられる場合に保存された値を上書きします。書き込み拒否がそれを拒否します。

別のコラムを再掲載するコラム

列を保留すると、同じ値を持つ列も2つ目の名前で差し止められます。Dataverseはこれらを作成します:ルックアップの …name と …yominame パートナー、選択肢のラベル、そして各通貨列ごとにベース通貨の双子( creditlimit_base creditlimitと並んで)。これらは通常の列なので、拒否リストの命名 creditlimit は creditlimit_base何も言わず、これがなければマスクされた金額はその双子を通って直接戻ってきます。リンクは命名ルールではなくプラットフォーム自身のメタデータから来るため、自分のカラムにも当てはまります。読み取り時、コンパニオンを明示的に名付けるクエリ、テーブルメタデータ、グリッドカラム、セーブデータにも適用されます。

ベストプラクティスは、ソースからフィルタリングすること

フレームワークがあなたに表示できないケースが一つあります。計算された列やロールアップの列、そしてプラットフォームの複合列(fullname、yomifullname、address1_compositeとその兄弟列)です。Dataverseはどの列がそれらを供給しているかを報告しないので、差し止めてもfullnamelastnameを差し止めることはなく、拒否した列の上に計算された列を割り当てても結果は表示されます。入力が敏感な場合は、自分で読み取りセットに名前を付けてください。許可リスト(ColumnPermissions.Allow(…))はこの問題を完全に回避します。なぜなら、名前を付けるまで何も読み取れないため、差し止めに値するものを保持するテーブルの方が良いデフォルトだからです。

注記

複数の提供者が1つのテーブルをカバーする場合、その列セットは操作と同じように構成されます。すなわち、役割をまたぐ加算的で、1つのグループ内で MultiplePermissionHandlersBehavior に分類されます。行のスコープのみを目的とし、列について何も言わない提供者は列折り目から完全に除外されるため、他の提供者が与えた内容を広げたり狭めたりしません。

Dataverse-Native Security (プレビュー)

今後推奨されるセキュリティモデルでは、 Dataverse自身 がPower Pagesの 統一されたDataverseセキュリティ 機能を基盤に、ポータルユーザーのためにセキュリティを強制できるようになります。権限ハンドラーをコードで書く代わりに、Power Pagesの ウェブロール や テーブル権限でアクセスを管理し、プラットフォームはそれらをDataverseのセキュリティロールに変換し、Dataverseはすべてのリクエストでそれを強制します。このモデルは現在 プレビュー 段階にあり、Microsoftの機能とPower Portals Proのサポートの両方が適用されており、Power Portals ProはMicrosoftのリリーススケジュールに従って一般提供されます。

有効化されると、PowerPortalsProは各ポータル連絡先に対してシステム管理(C2)systemuserを自動的にプロビジョニングします。新規連絡先の登録時と、既存連絡先のサインイン時に遅く対応する際の対応で、連絡先、システムユーザー、Power Pagesサイトをリンクするpowerpagesusermappingレコードも含まれます。セッションのDataverseコールはすべてそのシステムユーザーになりすまし、Power Pagesがあなたのウェブロールとテーブル権限から同期するセキュリティロールが、ユーザーが何を見たり何をしたりできるかを正確に管理します。セッションには多くのContactStubUserがPortalUserTypeされるため、UIはプロビジョニング済みユーザーと実際の内部ユーザーを常に区別できます。

注記

このセキュリティモデルを使うには、Dataverse環境内でPower Pagesのウェブサイトを作成する必要があります。これがMicrosoft Frameworkコンポーネントをインストールし、統一セキュリティ機能を有効にするためのものです。有料のPower Pagesプランは不要で、機能のインストールと有効化後はすぐにウェブサイト自体を削除できます。PowerPagesSiteIdが参照するPower Pagesのサイトレコード(powerpagesite)は環境内に存在している必要があります。なぜなら、ユーザーマッピングやセキュリティロール同期がそれに対してリゾリュートするからです。

Dataverseネイティブセキュリティの実現

サーバーのProgram.csでSecurityOptionsを有効にし、Power PagesのサイトアカウントのIDを入力してください:

構成はアプリケーション起動時に検証されます。 ProvisionSystemUsers が有効になったら、 PowerPagesSiteId を設定し、既存の powerpagesite レコードに解決しなければならず、そうでなければアプリケーションはガイダンスから起動できません。

Power Pagesと同じように、 Webロール や テーブル権限 を設定してください。Power Pages管理アプリや、Power Portals Pro Enhanced Authorizationソリューションの Webロール ページで、連絡先にウェブロールを割り当てます(管理アプリを通じて、プログラム的に、または同じページにルールを持つ新規ユーザーに自動で)。プラットフォームはそれらを自動生成されるセキュリティロール( PowerPages_*と名付けられた)に同期し、ウェブロールのメンバーシップ変更として自動的に割り当てます。設定は完全にPower Pages上で行われているため、ポータルは実際のPower Pagesサイトとスムーズに移動できます。役割や権限の変更は、Dataverseのキャッシュ内で伝播するまでに数秒から数分かかることがあります。

ステップバイステップのセットアップガイドに従ってください

外部サインインを連絡先に照合する

Microsoft、Google、またはその他の外部プロバイダーにサインインすると、ポータルはそのサインインがどの既存の連絡先(もしあれば)に属しているかを特定しなければなりません。この問題は2つのステップで解決されます。

  1. 既存のリンクです。 もしそのアカウントが以前にサインインしているなら、 adx_externalidentity 行ですでに連絡先に紐づけられます。これは明示的に保存された「このアカウントはこの人物です」という文で、常に勝利し、下記の設定に影響されません。
  2. メールのフォールバック。 まだリンクがありませんが、ポータルはプロバイダーが提供したメールアドレスと連絡先の列を照合します。このステップで設定できるものであり、リピーターが既存の連絡先に加入するか重複するかを決めます。

デフォルトでは2つの列を検索し、まずポータルのユーザー名を先に検索します。ポータルで作成された連絡先は adx_identity_username を持ちますが、スタッフがインポートまたは入力した連絡先は通常 emailaddress1 しか持たないことが多いです。両方を検索することで、既存の顧客がサインインして新しい記録ではなく自分の記録に表示できるようになります:

順序は重要です。順位は単なるリストではなく優先順位です。列は単一のクエリで一緒に検索され、リスト内で最初に一致した列が勝者を決定します。つまり、ある連絡先がそのアドレスをポータルのユーザー名として保持し、もう一方がemailaddress1に保持した場合、デフォルトの順序ではユーザー名の一致が勝ちます。

マッチングを絞るために列数を減らす: [ContactEmailColumn.IdentityUsername] はポータルで作成されたアカウントに限定し、空のリストはメールのフォールバックを完全にオフにし、既存の外部識別リンクだけがアカウントが連絡先に繋がる唯一の手段となります。 ContactEmailColumn.EmailAddress2 と ContactEmailColumn.EmailAddress3 を追加して範囲を広げましょう。これらは下記の理由から意図的にデフォルトから除外されています。

ベストプラクティスは、ソースからフィルタリングすること

あなたがリストするすべての列は、そのメールアドレスを管理する人がその連絡先として認識されるためのものです。リストリストは、データ入力プロセスが連絡先本人のものとみなす列のみを挙げます。もしチームがアシスタントの住所や共有会社の受信箱を登録している場合 emailaddress2 、その受信トレイを読んだ人がこの連絡先としてサインインできるようにします。

ベストプラクティスは、ソースからフィルタリングすること

マッチングはメールアドレスを単なるラベルではなく識別子にし、サインインがどの既存の連絡先になるかを決定します。つまり、ポータルは確認メールをスキップします。IDプロバイダーがその正確なアドレスを確認した場合だけです。もしアドレスがプロバイダーが提供したアドレスの上に入力されていたり、プロバイダーが確認しなかった場合、確認リンクが送信され、そのリンクをたどるまで外部ログインは連絡先に関連付けられません。

どのサインインが認証済みとみなされるかはプロバイダーの特性ではありません。Googleは主張するすべてのアドレスを検証します。 Microsoftは確認しません。 個人のMicrosoftアカウントがアドレスを認証しましたが、Entraの職場や学校アカウントはディレクトリの mail 属性を提供し、テナント管理者はテナントが所有していないドメインを含め、任意のドメインで任意の値に設定できます。ポータルは代わりにプロバイダーのトークンを読み取ります。個人アカウントが認証され、職場や学校のアカウントはEntraがその正確なアドレスを保証した場合のみ認証されます。例えば、Entraの verified_primary_email や verified_secondary_email の請求がそのアドレスを記載しているか、 xms_edov が自分のドメインがユーザー自身のテナントに属していると言っている場合だけです。Entraはアプリ登録時にのみこれらの請求を送信します( Entra IDサインイン設定参照)。これらがなければ、職場や学校のサインインは初回メールで確認されます。

注記

これらの設定は外部サインインにのみ適用されます。ローカルのユーザー名/パスワードサインイン、登録、パスワードリセットは adx_identity_username だけで意図的に一致し続けます。パスワードリセットフローは入力したアドレスへのリンクをメール送信するため、二次的なメール欄を照合することで誰かが他人のパスワードをリセットできるようになります。

既存の連絡先のみサインインを許可する

デフォルトでは誰でもポータルユーザーになれます。登録または外部プロバイダーで「No Contact」のアドレスでサインインすると、連絡先が作成されます。ポータルがDataverseで既に保持している人(顧客、メンバー、パートナー)向けの場合、サインアップをオフにし、その人だけがサインインできます:

レジスタページとそのリンクは消え、サーバーはどんな方法でもユーザーを作成しません。外部サインは上記のように連絡先を見つけてリンクします。誰も一致しないアカウントは、連絡先を作成する代わりに拒否されます。すでにローカルアカウントを持っている人には影響を受けません。

注記

サインイン拒否は、プロバイダーがその正確な住所を確認した場合にのみ画面上で説明されます。なぜなら、サインインした人はすでにその住所の所有者であることを証明しているからです。その他の住所については、ポータルは連絡先のある住所と同じように「メールを確認してください」と答え、登録されていないと短期間で通知します。訪問者に直接伝えれば、誰でもフォームに住所を入力して誰がアカウントを持っているか確認できます。

通知はポータル自身のメール送信者を通じて送信されます。それを自社のメールスタックに置き換えるホストも、 ISignUpRefusalEmailSenderを登録すべきです。がなければ拒否は記録され、通知は送信されません。

組み込みの基本クラス

このフレームワークは、一般的なセキュリティパターンを簡素化するための基本クラスを提供します:

API参照

AuthorizePortalRoleAttribute クラス

性質

名称
種類
デフォルト
概要
AuthenticationSchemesstring?
Policystring?
RoleNamesIReadOnlyList<string>
この属性に必要な役割名、いずれかがそれを満たす。
Rolesstring?
TypeIdObject
名称: AuthenticationSchemes
種類: string?
名称: Policy
種類: string?
名称: RoleNames
種類: IReadOnlyList<string>
概要: この属性に必要な役割名、いずれかがそれを満たす。
名称: Roles
種類: string?
名称: TypeId
種類: Object

方法

名称
パラメータ
種類
概要
IsDefaultAttributebool
MatchObject obj
bool
名称: IsDefaultAttribute
種類: bool
名称: Match
パラメータ: Object obj
種類: bool

ITablePermissionProvider Interface

性質

名称
種類
デフォルト
概要
Tablestring
このプロバイダーが適用されるテーブルの論理名。マッチングは正確に一致しているので、 Dataverseの論理名は小文字で表記します。
名称: Table
種類: string
概要: このプロバイダーが適用されるテーブルの論理名。マッチングは正確に一致しているので、 Dataverseの論理名は小文字で表記します。

方法

名称
パラメータ
種類
概要
GetPermissionsAsyncUserInfo user
Task<TablePermissions>
この表 user どうすればいいのか、どの列を読むのか そして書きます。アクセスできないはずのユーザーに TablePermissions.None を返します。 操作はテーブルレベルのゲートであり、行フィルターではありません:grant TableSecurityPermission.Read ユーザーがテーブルの どれか を見ることができるかどうか 行と Services.TableQueryContext)のどの項目をスコープするか。 列はオプトイン(選択)です。 名前が付けられるまでは何も読み書きできません — 許可 TableSecurityPermission.Read だけではレコードのIDのみが露出します。使用 Reading(System.String[]) および Writing(System.String[]) 名前をつけるか、あるいは このテーブルではカラムセキュリティをオプトアウトする TablePermissions.AllColumns 。 行のスコープだけを目的としたプロバイダーは、列を完全に放置することも可能です — 何も言いません 彼らについてであり、意見を述べるものではなく、他者の関係を広げることも狭めることもありません テーブル上の提供者は認められます。何も言わない場合でも全体として失敗クローズドです:ノーの場合 プロバイダーは列名を付けますが、どれも読み取れません。 各テーブルごとにユーザーごとに1つずつ呼び出し、リクエストのためにキャッシュされるため、コストも同じくらい高くなることがあります そうでなければならない。
GetQueryFilterAsyncTableQueryContext context
Task<TableQueryFilter>
ユーザーがこのテーブルのどの行に対応できるかのスコープ:以下で構築されたフィルター Query.LogicalOperator)、TableQueryFilter.AllRows 操作が許す行を、行がない場合はnull。 閉じられた行は 失敗します。プロバイダーはどの行を認めるかを指定しなければなりません。同じように 列名を挙げる:null — または条件のないフィルター — は条件を与えないので テーブルのスコープを忘れることは、すべての行を公開する代わりにそれを否定します。例えば TableQueryFilter.AllRows、あなたが言いたいのは「すべての列」のことです。 フィルターはDataverseがクエリを実行する前に追加されるため、ユーザーが見られない行は以下の通りです 決して取得されません。これはポータルがテーブルに発行するすべてのクエリに適用されます:グリッド、ルックアップ、 サブグリッド、チャート、単一レコードのロード、さらに更新前のプリフライト取得や delete(削除)—これがTableQueryContext.Operationが区別する点です。また、実行も行います 両方のセキュリティモデルの下で、Dataverseネイティブのセキュリティでも有効に保たれます Services.UserInfo)をバイパスします。 フレームワークはフィルターの組み合わせを決めるものであり、プロバイダーではありません。プロバイダーからのフィルター 同じグループでは、同じ役割の2つの提供者が一致するはずです。フィルター 異なる役割の連合であり、別の役割を持つことで見える範囲が広がり、どのように対応するかを認識します。 操作を合成します。PortalRoleOptions.CompositionBehavior を に設定します。 また、役割をまたいで交差するのも良いRoleCompositionBehavior.Restrictiveです。 グループ内で提供者がnull応答すると、グループに行が残りません。 TableQueryFilter.AllRows他のプロバイダーのフィルターに任せます。横断 グループは、TableQueryFilter.AllRowsを付与するグループでデフォルトの加算を広げます すべての行に統合 — つまり、ロールのフィルターは他のグループが テーブルのフィルターも同様です。
名称: GetPermissionsAsync
パラメータ: UserInfo user
種類: Task<TablePermissions>
概要: この表 user どうすればいいのか、どの列を読むのか そして書きます。アクセスできないはずのユーザーに TablePermissions.None を返します。 操作はテーブルレベルのゲートであり、行フィルターではありません:grant TableSecurityPermission.Read ユーザーがテーブルの どれか を見ることができるかどうか 行と Services.TableQueryContext)のどの項目をスコープするか。 列はオプトイン(選択)です。 名前が付けられるまでは何も読み書きできません — 許可 TableSecurityPermission.Read だけではレコードのIDのみが露出します。使用 Reading(System.String[]) および Writing(System.String[]) 名前をつけるか、あるいは このテーブルではカラムセキュリティをオプトアウトする TablePermissions.AllColumns 。 行のスコープだけを目的としたプロバイダーは、列を完全に放置することも可能です — 何も言いません 彼らについてであり、意見を述べるものではなく、他者の関係を広げることも狭めることもありません テーブル上の提供者は認められます。何も言わない場合でも全体として失敗クローズドです:ノーの場合 プロバイダーは列名を付けますが、どれも読み取れません。 各テーブルごとにユーザーごとに1つずつ呼び出し、リクエストのためにキャッシュされるため、コストも同じくらい高くなることがあります そうでなければならない。
名称: GetQueryFilterAsync
パラメータ: TableQueryContext context
種類: Task<TableQueryFilter>
概要: ユーザーがこのテーブルのどの行に対応できるかのスコープ:以下で構築されたフィルター Query.LogicalOperator)、TableQueryFilter.AllRows 操作が許す行を、行がない場合はnull。 閉じられた行は 失敗します。プロバイダーはどの行を認めるかを指定しなければなりません。同じように 列名を挙げる:null — または条件のないフィルター — は条件を与えないので テーブルのスコープを忘れることは、すべての行を公開する代わりにそれを否定します。例えば TableQueryFilter.AllRows、あなたが言いたいのは「すべての列」のことです。 フィルターはDataverseがクエリを実行する前に追加されるため、ユーザーが見られない行は以下の通りです 決して取得されません。これはポータルがテーブルに発行するすべてのクエリに適用されます:グリッド、ルックアップ、 サブグリッド、チャート、単一レコードのロード、さらに更新前のプリフライト取得や delete(削除)—これがTableQueryContext.Operationが区別する点です。また、実行も行います 両方のセキュリティモデルの下で、Dataverseネイティブのセキュリティでも有効に保たれます Services.UserInfo)をバイパスします。 フレームワークはフィルターの組み合わせを決めるものであり、プロバイダーではありません。プロバイダーからのフィルター 同じグループでは、同じ役割の2つの提供者が一致するはずです。フィルター 異なる役割の連合であり、別の役割を持つことで見える範囲が広がり、どのように対応するかを認識します。 操作を合成します。PortalRoleOptions.CompositionBehavior を に設定します。 また、役割をまたいで交差するのも良いRoleCompositionBehavior.Restrictiveです。 グループ内で提供者がnull応答すると、グループに行が残りません。 TableQueryFilter.AllRows他のプロバイダーのフィルターに任せます。横断 グループは、TableQueryFilter.AllRowsを付与するグループでデフォルトの加算を広げます すべての行に統合 — つまり、ロールのフィルターは他のグループが テーブルのフィルターも同様です。

TablePermissions クラス

性質

名称
種類
デフォルト
概要
ColumnsTableColumnPermissions
ユーザーが読む・書くことができる列。 TableColumnPermissions.None 何かに名前が付けられています:列へのアクセスは許可されるもので、決して仮定されません。
OperationsTableSecurityPermission
ユーザーがテーブル上で行う操作はフラグ値として行われます。これはテーブルレベルです 行フィルターではなくゲート — ユーザーが可能であれば含めて TableSecurityPermission.Read テーブルの どの行でも 確認し、どの行をスコープするか Services.TableQueryContext)。
名称: Columns
種類: TableColumnPermissions
概要: ユーザーが読む・書くことができる列。 TableColumnPermissions.None 何かに名前が付けられています:列へのアクセスは許可されるもので、決して仮定されません。
名称: Operations
種類: TableSecurityPermission
概要: ユーザーがテーブル上で行う操作はフラグ値として行われます。これはテーブルレベルです 行フィルターではなくゲート — ユーザーが可能であれば含めて TableSecurityPermission.Read テーブルの どの行でも 確認し、どの行をスコープするか Services.TableQueryContext)。

方法

名称
パラメータ
種類
概要
AllColumnsTablePermissions
カラムレベルのセキュリティを完全に除外し、すべてのカラムが読み書き可能であることを選びます。その コラムセキュリティ以前の挙動で、継承されるのではなく明確に示されています。
AllowTableSecurityPermission operations
TablePermissions
この値がすでに提供しているものに operations を加えます。
AllowingTableSecurityPermission operations
TablePermissions
operationsを付与し、柱はなし。鎖のReading(System.String[])、 Writing(System.String[])やTablePermissions.ReadingAllColumnsで列を開けることができます。
Readingstring[] columns
TablePermissions
既に許可されている列に加えて、名前のある列の閲覧を許可します。大文字を区別しません。 つまり、メイカーポータルの綴りも論理的な名前も使えます。
ReadingAllColumnsTablePermissions
このテーブルのカラムレベルの読み取りセキュリティのオプトアウト:すべての列(追加された列も含む) 後でテーブルに。意図的に明示的に — フレームワークはそれを前提にしません。
ReadingAllColumnsExceptstring[] columns
TablePermissions
列レベルの読み取りセキュリティは、名前付き列を除くすべての列にオプトアウトします。 これらは後から追加されたものも含めて。新しいものは無効なので、 機密データが保管されているテーブルに、 Reading(System.String[]) 。
ReadingAndWritingstring[] columns
TablePermissions
名前のある列の読み書きの両方が可能です。
WithColumnsTableColumnPermissions columns
TablePermissions
カラムルールを丸ごと置き換え、プロバイダーが Services.TableColumnPermissions 流暢な手法を連鎖させる。
WithholdingWithheldColumnBehavior behavior
TablePermissions
この表の保留された列がどのように戻ってくるか――省略されたのか、マスクされた数値で現れるのか。 このテーブルのサイト全体の SecurityOptions.WithheldColumnBehavior を上書きします。
Writingstring[] columns
TablePermissions
レコードが作成されるときと更新されたとき、名前付きの列を書き込むことを許可します すでに許可されているものに加えることができます。コラムを書くことは読むことを意味するのではなく、名前を付けてください もしユーザーが自分の書いた内容を見られるなら、 Reading(System.String[]) も。
WritingAllColumnsTablePermissions
このテーブルのカラムレベルの書き込みセキュリティをオプトアウトします:ユーザーは任意の列を書き込むことができます。 作成時と更新時の両方。両方の書き込みセットを置き換えるので、呼び出します。 WritingOnCreate(System.String[]) / WritingOnUpdate(System.String[]) はその前にではなく、その後です。
WritingAllColumnsExceptstring[] columns
TablePermissions
列レベルの書き込みセキュリティはオプトアウトしますが、名前付き列は読み取り専用のままです。 両方の書き込みセットを置き換えるので、 WritingOnCreate(System.String[]) / WritingOnUpdate(System.String[]) その前ではなく、その後に。
WritingOnCreatestring[] columns
TablePermissions
レコードが作成されたときに名前付き列を設定することを許可し、その時点でのみ記録が存在します これらは読み取り専用であり、以前の呼び出しであっても — Writing(System.String[])TablePermissions.WritingAllColumns — 書くことができるものにした。事件の優先事項、選ばれた時のことだ それ以降はログされ修正されました。 WritingAllColumns...の後を継いで呼び、置き換えます どちらも集合を書きます。 Writing(System.String[])と同様に、読むことを意味しません。
WritingOnUpdatestring[] columns
TablePermissions
既存のレコードで名前の列を変更することは許可しますが、設定する場合は変更できません 作成された、たとえ以前の呼び出しで書き取れるものになっていても — 決議メモは ケースが存在すると、何かを使います。 WritingAllColumns...の後を継いで呼びます。これは どちらも集合を書きます。 Writing(System.String[])と同様に、読み取ることを意味しません。
名称: AllColumns
種類: TablePermissions
概要: カラムレベルのセキュリティを完全に除外し、すべてのカラムが読み書き可能であることを選びます。その コラムセキュリティ以前の挙動で、継承されるのではなく明確に示されています。
名称: Allow
パラメータ: TableSecurityPermission operations
種類: TablePermissions
概要: この値がすでに提供しているものに operations を加えます。
名称: Allowing
パラメータ: TableSecurityPermission operations
種類: TablePermissions
概要: operationsを付与し、柱はなし。鎖のReading(System.String[])、 Writing(System.String[])やTablePermissions.ReadingAllColumnsで列を開けることができます。
名称: Reading
パラメータ: string[] columns
種類: TablePermissions
概要: 既に許可されている列に加えて、名前のある列の閲覧を許可します。大文字を区別しません。 つまり、メイカーポータルの綴りも論理的な名前も使えます。
名称: ReadingAllColumns
種類: TablePermissions
概要: このテーブルのカラムレベルの読み取りセキュリティのオプトアウト:すべての列(追加された列も含む) 後でテーブルに。意図的に明示的に — フレームワークはそれを前提にしません。
名称: ReadingAllColumnsExcept
パラメータ: string[] columns
種類: TablePermissions
概要: 列レベルの読み取りセキュリティは、名前付き列を除くすべての列にオプトアウトします。 これらは後から追加されたものも含めて。新しいものは無効なので、 機密データが保管されているテーブルに、 Reading(System.String[]) 。
名称: ReadingAndWriting
パラメータ: string[] columns
種類: TablePermissions
概要: 名前のある列の読み書きの両方が可能です。
名称: WithColumns
パラメータ: TableColumnPermissions columns
種類: TablePermissions
概要: カラムルールを丸ごと置き換え、プロバイダーが Services.TableColumnPermissions 流暢な手法を連鎖させる。
名称: Withholding
パラメータ: WithheldColumnBehavior behavior
種類: TablePermissions
概要: この表の保留された列がどのように戻ってくるか――省略されたのか、マスクされた数値で現れるのか。 このテーブルのサイト全体の SecurityOptions.WithheldColumnBehavior を上書きします。
名称: Writing
パラメータ: string[] columns
種類: TablePermissions
概要: レコードが作成されるときと更新されたとき、名前付きの列を書き込むことを許可します すでに許可されているものに加えることができます。コラムを書くことは読むことを意味するのではなく、名前を付けてください もしユーザーが自分の書いた内容を見られるなら、 Reading(System.String[]) も。
名称: WritingAllColumns
種類: TablePermissions
概要: このテーブルのカラムレベルの書き込みセキュリティをオプトアウトします:ユーザーは任意の列を書き込むことができます。 作成時と更新時の両方。両方の書き込みセットを置き換えるので、呼び出します。 WritingOnCreate(System.String[]) / WritingOnUpdate(System.String[]) はその前にではなく、その後です。
名称: WritingAllColumnsExcept
パラメータ: string[] columns
種類: TablePermissions
概要: 列レベルの書き込みセキュリティはオプトアウトしますが、名前付き列は読み取り専用のままです。 両方の書き込みセットを置き換えるので、 WritingOnCreate(System.String[]) / WritingOnUpdate(System.String[]) その前ではなく、その後に。
名称: WritingOnCreate
パラメータ: string[] columns
種類: TablePermissions
概要: レコードが作成されたときに名前付き列を設定することを許可し、その時点でのみ記録が存在します これらは読み取り専用であり、以前の呼び出しであっても — Writing(System.String[])TablePermissions.WritingAllColumns — 書くことができるものにした。事件の優先事項、選ばれた時のことだ それ以降はログされ修正されました。 WritingAllColumns...の後を継いで呼び、置き換えます どちらも集合を書きます。 Writing(System.String[])と同様に、読むことを意味しません。
名称: WritingOnUpdate
パラメータ: string[] columns
種類: TablePermissions
概要: 既存のレコードで名前の列を変更することは許可しますが、設定する場合は変更できません 作成された、たとえ以前の呼び出しで書き取れるものになっていても — 決議メモは ケースが存在すると、何かを使います。 WritingAllColumns...の後を継いで呼びます。これは どちらも集合を書きます。 Writing(System.String[])と同様に、読み取ることを意味しません。

AuthClientOptions クラス

性質

名称
種類
デフォルト
概要
LocalAccountsEnabledbool
True
ポータルがローカルのユーザー名やパスワードアカウントを受け入れているかどうか。デフォルトは trueです。 内部専用ポータル(Microsoft/Entraサインインのみ)では false に設定してください。 これにより、UIだけでなくサーバー上のローカルアカウントがオフになります。 MapAuthEndpoints パスワードのログイン、登録、パスワードリセット、設定や変更をマッピングしません パスワードか二要素管理、つまり404ルートです。ポータルのアイデンティティ層 また、パスワードサインインを拒否し、パスワードの作成、追加、変更、リセットも拒否します。 サーバーレンダリングされたアカウントページもカバーしています。外部プロバイダーを通じてサインインしてください。 メール確認、プロフィール、外部ログイン管理、個人データダウンロード アカウント削除は影響を受けません。 クライアントはローカルのログインフォームやレジスタ/パスワードリセットページを隠すために読み取ります。 既存アカウントに保存されているパスワードはDataverseに残りますが、もう保存できません サインインしていました。
SignUpEnabledbool
True
サインインすることでポータルユーザーを作成できるかどうか。デフォルトは true:登録した人、または 外部プロバイダーで住所を登録し、新しい連絡先が登録されます。 すでに連絡先を持っている人だけがサインインできるように falseに設定 しています。 オフでも外部サインインは既存の連絡先と一致します — 以前のリンクや SecurityOptions.ContactMatching のメール欄で、そしてそれへのリンクを郵送して 提供者が住所を保証しなかった場合はまず確認してください。サインインで一致しない 連絡を拒否する代わりに、連絡先が作成されません。サインインする人には、 プロバイダーが住所を確認しました。そうでなければ住所は通知で郵送され、サインインは 一致するものとして回答したため、フォームでどの住所が 連絡。 MapAuthEndpoints は登録をマッピングしていないため、ルート404と portalのIdentityレイヤーはユーザーの作成を拒否しており、サーバーレンダリングアカウントをカバーしています ページも。 クライアントはレジスターのページとリンクを隠し、サインイン拒否の説明のためにこれを読みます。
名称: LocalAccountsEnabled
種類: bool
デフォルト: True
概要: ポータルがローカルのユーザー名やパスワードアカウントを受け入れているかどうか。デフォルトは trueです。 内部専用ポータル(Microsoft/Entraサインインのみ)では false に設定してください。 これにより、UIだけでなくサーバー上のローカルアカウントがオフになります。 MapAuthEndpoints パスワードのログイン、登録、パスワードリセット、設定や変更をマッピングしません パスワードか二要素管理、つまり404ルートです。ポータルのアイデンティティ層 また、パスワードサインインを拒否し、パスワードの作成、追加、変更、リセットも拒否します。 サーバーレンダリングされたアカウントページもカバーしています。外部プロバイダーを通じてサインインしてください。 メール確認、プロフィール、外部ログイン管理、個人データダウンロード アカウント削除は影響を受けません。 クライアントはローカルのログインフォームやレジスタ/パスワードリセットページを隠すために読み取ります。 既存アカウントに保存されているパスワードはDataverseに残りますが、もう保存できません サインインしていました。
名称: SignUpEnabled
種類: bool
デフォルト: True
概要: サインインすることでポータルユーザーを作成できるかどうか。デフォルトは true:登録した人、または 外部プロバイダーで住所を登録し、新しい連絡先が登録されます。 すでに連絡先を持っている人だけがサインインできるように falseに設定 しています。 オフでも外部サインインは既存の連絡先と一致します — 以前のリンクや SecurityOptions.ContactMatching のメール欄で、そしてそれへのリンクを郵送して 提供者が住所を保証しなかった場合はまず確認してください。サインインで一致しない 連絡を拒否する代わりに、連絡先が作成されません。サインインする人には、 プロバイダーが住所を確認しました。そうでなければ住所は通知で郵送され、サインインは 一致するものとして回答したため、フォームでどの住所が 連絡。 MapAuthEndpoints は登録をマッピングしていないため、ルート404と portalのIdentityレイヤーはユーザーの作成を拒否しており、サーバーレンダリングアカウントをカバーしています ページも。 クライアントはレジスターのページとリンクを隠し、サインイン拒否の説明のためにこれを読みます。