質問編集履歴

2

まとめの追加

2021/03/01 04:18

投稿

woodcube
woodcube

スコア32

test CHANGED
File without changes
test CHANGED
@@ -223,3 +223,17 @@
223
223
  ### 補足情報(FW/ツールのバージョンなど)
224
224
 
225
225
  ASP.NET CORE razore
226
+
227
+
228
+
229
+
230
+
231
+ ### 解決した内容のまとめ
232
+
233
+ - User (ClaimsPrincipal) は必ず生成されるので、そこにあるIsInRole()を使えばよい。
234
+
235
+ - 認証クッキーに含まれる認証チケットから生成するのでDBアクセスは行われない為、パフォーマンスは気にしなくて良い。
236
+
237
+ - ↑上記2つに事から、コード中やhtmlの中でその都度IsInRole()で判定する方法で良い
238
+
239
+ - ページ全体をロールの判断で制御する場合は[Authorize(Roles = "Administrator")] の方法が良い(オマケ)

1

具体的な使用方法をソースを追記しました

2021/03/01 04:18

投稿

woodcube
woodcube

スコア32

test CHANGED
File without changes
test CHANGED
@@ -10,6 +10,174 @@
10
10
 
11
11
 
12
12
 
13
+ ### 具体的にやろうとしていること
14
+
15
+ - 利用ユーザ、店舗オーナ、管理者の3種類のロールがあります。
16
+
17
+ - 店舗は、1つの店舗情報に対してイベントを複数作る事ができます。
18
+
19
+ - 匿名または利用ユーザは、店舗情報とイベントを見る事ができます。
20
+
21
+ - 店舗オーナは、自分の店舗とイベントの情報の変更ができますが、他オーナのは変更できません(利用ユーザと同じ権限)
22
+
23
+ - 管理者は、全部の店舗情報、イベントの変更ができます。
24
+
25
+
26
+
27
+ 例えば、
28
+
29
+ 「ユーザ詳細情報」というのを表示すると、
30
+
31
+ 利用ユーザの場合は自分のプロフィールが見れます。
32
+
33
+ 利用ユーザの場合は、店舗情報の項目は表示されません。
34
+
35
+ 店舗オーナの場合は、所有する店舗の情報が追加で表示されます。
36
+
37
+ 管理者以外は他人の「ユーザ詳細情報」の表示はできません。
38
+
39
+
40
+
41
+ 他にも、serIDの値を店舗オーナーの場合は、自分のUserIDのみ可。管理者ならどのIDでも可という様にロールによって可能な範囲が変わる使い方を考えています。
42
+
43
+ これらの制御をロールで行いたいのですが、毎回IsInRoleAsync()で取得をするものなのか?が知りたいです。
44
+
45
+
46
+
47
+
48
+
49
+ **↓今は、こういう感じで動作させています。**
50
+
51
+ ![イメージ説明](8fcd34d4e37a05424029a599b428a238.png)
52
+
53
+ ```html
54
+
55
+
56
+
57
+
58
+
59
+ @if (Model.OwnerFlg)
60
+
61
+ {
62
+
63
+ <div>
64
+
65
+ <h4>■所有店舗情報(StoreTbl)</h4>
66
+
67
+ <table class="table">
68
+
69
+ <thead>
70
+
71
+ <tr>
72
+
73
+ <th>
74
+
75
+ @Html.DisplayNameFor(model => model.StoreTbls[0].StoreTblId)
76
+
77
+ </th>
78
+
79
+ <th>
80
+
81
+ @Html.DisplayNameFor(model => model.StoreTbls[0].OwnerTblId)
82
+
83
+ ```
84
+
85
+ ```C#
86
+
87
+ public bool AdminFlg;
88
+
89
+ public bool OwnerFlg;
90
+
91
+
92
+
93
+ public async Task<IActionResult> OnGetAsync(string id)
94
+
95
+ {
96
+
97
+ AdminFlg = false;
98
+
99
+ OwnerFlg = false;
100
+
101
+
102
+
103
+ var user = await _userManager.GetUserAsync(User);
104
+
105
+ if (user == null)
106
+
107
+ {
108
+
109
+ //存在しないユーザは表示できない
110
+
111
+ return NotFound($"ユーザが存在しません ID = '{_userManager.GetUserId(User)}'.");
112
+
113
+ }
114
+
115
+
116
+
117
+ //ロール情報の取得
118
+
119
+ if (await _userManager.IsInRoleAsync(user, "Admin") == true) { AdminFlg = true; }
120
+
121
+ if (await _userManager.IsInRoleAsync(user, "Owner") == true) { OwnerFlg = true; }
122
+
123
+
124
+
125
+ //id指定が無い場合は自分を表示
126
+
127
+ if (id == null) { id = user.Id; }
128
+
129
+
130
+
131
+ //管理者でなければ他人の情報は見れない
132
+
133
+ if (AdminFlg == false)
134
+
135
+ {
136
+
137
+ if (id != user.Id)
138
+
139
+ {
140
+
141
+ return NotFound($"他人の情報は見れません ID = '{_userManager.GetUserId(User)}'.");
142
+
143
+ }
144
+
145
+ }
146
+
147
+
148
+
149
+ //ユーザのプロフィールを取得
150
+
151
+ App01StoreFindUser = await _context.App01StoreFindUser.FirstOrDefaultAsync(m => m.Id == id);
152
+
153
+ if (App01StoreFindUser == null)
154
+
155
+ {
156
+
157
+ return NotFound();
158
+
159
+ }
160
+
161
+
162
+
163
+ //オーナーの場合、所有する店の一覧を表示する
164
+
165
+ if (OwnerFlg == true)
166
+
167
+ {
168
+
169
+ var stores = await _datacontext.StoreTbl.
170
+
171
+ OrderBy(stores => stores.StoreTblId).ToListAsync();
172
+
173
+ }
174
+
175
+ ```
176
+
177
+
178
+
179
+
180
+
13
181
  ### 自分で考えたり試した方法
14
182
 
15
183
  0. 関数(OnGetAsyncなど)の呼び出される都度、if (await _userManager.IsInRoleAsync(user, "Admin") == true) { }
@@ -42,7 +210,11 @@
42
210
 
43
211
  DBとのデータアクセスの方が遥かにコストが高いので気にする事は無いのかもしれませんが
44
212
 
45
-
213
+ - リスト1つの関数内であれば、関数の先頭で取得して、AdminFlgを覚えておけば良いですが、
214
+
215
+ ページが複数あるのでそれぞれの、ユーザの情報や、店舗情報、イベントのページでGetやPostが呼ばれる毎に毎回IsInRoleAsync()で取得するのは、当然の事なのでしょうか?
216
+
217
+ これらの処理を行う共通関数を用意して、OnGetなどの各関数の先頭でuserManager、User、AdminFlg、OwnerFlgを引数にして呼ぶ・・・というよりは、これらの要素を持ったクラスを生成する?のが良いのでしょうか?
46
218
 
47
219
 
48
220