質問編集履歴
2
まとめの追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -110,4 +110,11 @@
|
|
110
110
|
|
111
111
|
|
112
112
|
### 補足情報(FW/ツールのバージョンなど)
|
113
|
-
ASP.NET CORE razore
|
113
|
+
ASP.NET CORE razore
|
114
|
+
|
115
|
+
|
116
|
+
### 解決した内容のまとめ
|
117
|
+
- User (ClaimsPrincipal) は必ず生成されるので、そこにあるIsInRole()を使えばよい。
|
118
|
+
- 認証クッキーに含まれる認証チケットから生成するのでDBアクセスは行われない為、パフォーマンスは気にしなくて良い。
|
119
|
+
- ↑上記2つに事から、コード中やhtmlの中でその都度IsInRole()で判定する方法で良い
|
120
|
+
- ページ全体をロールの判断で制御する場合は[Authorize(Roles = "Administrator")] の方法が良い(オマケ)
|
1
具体的な使用方法をソースを追記しました
title
CHANGED
File without changes
|
body
CHANGED
@@ -4,6 +4,90 @@
|
|
4
4
|
public async Task<IActionResult> OnGetAsync()や、
|
5
5
|
public async Task<IActionResult> OnPostAsync()単位でその都度チェックするべきでしょうか?
|
6
6
|
|
7
|
+
### 具体的にやろうとしていること
|
8
|
+
- 利用ユーザ、店舗オーナ、管理者の3種類のロールがあります。
|
9
|
+
- 店舗は、1つの店舗情報に対してイベントを複数作る事ができます。
|
10
|
+
- 匿名または利用ユーザは、店舗情報とイベントを見る事ができます。
|
11
|
+
- 店舗オーナは、自分の店舗とイベントの情報の変更ができますが、他オーナのは変更できません(利用ユーザと同じ権限)
|
12
|
+
- 管理者は、全部の店舗情報、イベントの変更ができます。
|
13
|
+
|
14
|
+
例えば、
|
15
|
+
「ユーザ詳細情報」というのを表示すると、
|
16
|
+
利用ユーザの場合は自分のプロフィールが見れます。
|
17
|
+
利用ユーザの場合は、店舗情報の項目は表示されません。
|
18
|
+
店舗オーナの場合は、所有する店舗の情報が追加で表示されます。
|
19
|
+
管理者以外は他人の「ユーザ詳細情報」の表示はできません。
|
20
|
+
|
21
|
+
他にも、serIDの値を店舗オーナーの場合は、自分のUserIDのみ可。管理者ならどのIDでも可という様にロールによって可能な範囲が変わる使い方を考えています。
|
22
|
+
これらの制御をロールで行いたいのですが、毎回IsInRoleAsync()で取得をするものなのか?が知りたいです。
|
23
|
+
|
24
|
+
|
25
|
+
**↓今は、こういう感じで動作させています。**
|
26
|
+

|
27
|
+
```html
|
28
|
+
|
29
|
+
|
30
|
+
@if (Model.OwnerFlg)
|
31
|
+
{
|
32
|
+
<div>
|
33
|
+
<h4>■所有店舗情報(StoreTbl)</h4>
|
34
|
+
<table class="table">
|
35
|
+
<thead>
|
36
|
+
<tr>
|
37
|
+
<th>
|
38
|
+
@Html.DisplayNameFor(model => model.StoreTbls[0].StoreTblId)
|
39
|
+
</th>
|
40
|
+
<th>
|
41
|
+
@Html.DisplayNameFor(model => model.StoreTbls[0].OwnerTblId)
|
42
|
+
```
|
43
|
+
```C#
|
44
|
+
public bool AdminFlg;
|
45
|
+
public bool OwnerFlg;
|
46
|
+
|
47
|
+
public async Task<IActionResult> OnGetAsync(string id)
|
48
|
+
{
|
49
|
+
AdminFlg = false;
|
50
|
+
OwnerFlg = false;
|
51
|
+
|
52
|
+
var user = await _userManager.GetUserAsync(User);
|
53
|
+
if (user == null)
|
54
|
+
{
|
55
|
+
//存在しないユーザは表示できない
|
56
|
+
return NotFound($"ユーザが存在しません ID = '{_userManager.GetUserId(User)}'.");
|
57
|
+
}
|
58
|
+
|
59
|
+
//ロール情報の取得
|
60
|
+
if (await _userManager.IsInRoleAsync(user, "Admin") == true) { AdminFlg = true; }
|
61
|
+
if (await _userManager.IsInRoleAsync(user, "Owner") == true) { OwnerFlg = true; }
|
62
|
+
|
63
|
+
//id指定が無い場合は自分を表示
|
64
|
+
if (id == null) { id = user.Id; }
|
65
|
+
|
66
|
+
//管理者でなければ他人の情報は見れない
|
67
|
+
if (AdminFlg == false)
|
68
|
+
{
|
69
|
+
if (id != user.Id)
|
70
|
+
{
|
71
|
+
return NotFound($"他人の情報は見れません ID = '{_userManager.GetUserId(User)}'.");
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
//ユーザのプロフィールを取得
|
76
|
+
App01StoreFindUser = await _context.App01StoreFindUser.FirstOrDefaultAsync(m => m.Id == id);
|
77
|
+
if (App01StoreFindUser == null)
|
78
|
+
{
|
79
|
+
return NotFound();
|
80
|
+
}
|
81
|
+
|
82
|
+
//オーナーの場合、所有する店の一覧を表示する
|
83
|
+
if (OwnerFlg == true)
|
84
|
+
{
|
85
|
+
var stores = await _datacontext.StoreTbl.
|
86
|
+
OrderBy(stores => stores.StoreTblId).ToListAsync();
|
87
|
+
}
|
88
|
+
```
|
89
|
+
|
90
|
+
|
7
91
|
### 自分で考えたり試した方法
|
8
92
|
0. 関数(OnGetAsyncなど)の呼び出される都度、if (await _userManager.IsInRoleAsync(user, "Admin") == true) { }
|
9
93
|
を実行して正常に動作する事は確認できています。
|
@@ -20,8 +104,10 @@
|
|
20
104
|
ロールチェックやセッション変数の使い方が分っていても、実際の具体的な実装方法が知りたいです。
|
21
105
|
- 「IsInRoleAsync()を毎回使う」のと、「その結果をセッション変数に入れておく」方法のコスト差(主に実行時の速度パフォーマンス)が気になります。
|
22
106
|
DBとのデータアクセスの方が遥かにコストが高いので気にする事は無いのかもしれませんが
|
107
|
+
- リスト1つの関数内であれば、関数の先頭で取得して、AdminFlgを覚えておけば良いですが、
|
108
|
+
ページが複数あるのでそれぞれの、ユーザの情報や、店舗情報、イベントのページでGetやPostが呼ばれる毎に毎回IsInRoleAsync()で取得するのは、当然の事なのでしょうか?
|
109
|
+
これらの処理を行う共通関数を用意して、OnGetなどの各関数の先頭でuserManager、User、AdminFlg、OwnerFlgを引数にして呼ぶ・・・というよりは、これらの要素を持ったクラスを生成する?のが良いのでしょうか?
|
23
110
|
|
24
111
|
|
25
|
-
|
26
112
|
### 補足情報(FW/ツールのバージョンなど)
|
27
113
|
ASP.NET CORE razore
|