Skip to content

api/users の実行権限 ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

ユーザ API(/api/users/...)は、テナント管理者でなくても一部の操作ができます。1.5.8.1 のソースでの判定をまとめます。

  • Get は API が使えるユーザなら誰でも実行でき、同じテナントの全ユーザを取得できる。画面のユーザ管理と違い、テナント管理者かどうかを見ない
  • Update は自分自身(/api/users/{自分のUserId}/Update)なら一般ユーザでも実行できる。変えられる列は、列ごとの既定のアクセス制御で決まる
  • Create・Delete・Import はテナント管理者(または特権ユーザ)だけ。委任管理(EnableManageTenant)のユーザにはできない

管理権限の種類(特権ユーザ・テナント管理者・委任管理)とコントローラごとの判定の全体は アクセス権限の実装 を参照してください。

エンドポイント ​

ルーティングは Controllers/Api/UsersController.cs の属性ルーティングで、すべて POST です(UsersController.cs)。

ルート処理使う検証
api/users/Get、api/users/{id}/GetUserUtilities.GetByApiUserValidators.OnEntry
api/users/CreateUserUtilities.CreateByApiUserValidators.OnCreating
api/users/{id}/UpdateUserUtilities.UpdateByApiUserValidators.OnUpdating
api/users/{id}/DeleteUserUtilities.DeleteByApiUserValidators.OnDeleting
api/users/ImportUserUtilities.ImportByApiUserValidators.OnImporting

コントローラには [AllowAnonymous] と [CheckApiContextAttributes] が付いています。[AllowAnonymous] は ASP.NET Core の認証を素通りさせるだけで、各アクションが context.Authenticated を確かめ、未認証なら Unauthorized を返します。

全操作に共通の事前チェック ​

図を読み込み中…

CheckApiContextAttributes は、リクエストボディの有無、Security.json の AllowIpAddresses による IP 制限、契約設定の IP 制限、JSON の妥当性、TokenCheck 有効時のトークンを確かめます(CheckApiContextAttributes.cs)。

Validators.ValidateApi は、次のどれかに当たると InvalidRequest(403)を返します(Validators.cs#L72-L94)。サーバースクリプトから呼ばれた場合(serverScript: true)はこの 3 つを確かめません。

  • Api.json の Enabled が false
  • 契約設定で API が無効
  • UserSettings.AllowApi() が false

AllowApi() はユーザの「API を許可」列だけで決まるわけではありません(UserSettings.cs#L102-L108)。

text
特権ユーザなら true。それ以外は
(User.json の DisableApi も テナントの DisableApi も false  または  ユーザの AllowApi が true)
  かつ  UserSettings の DisableApi が true でない

既定(User.json の DisableApi が false)では全ユーザが API を使えます。ユーザの「API を許可」列が効くのは、パラメータかテナントで API を無効にしたときだけです。

操作ごとの判定 ​

判定に出てくるメソッドの中身は次のとおりです(Permissions.cs#L450-L705、#L770-L795)。context.Id は URL の {id}、context.UserId はログインユーザです。

メソッド(users の場合)条件
CanManageTenantテナント管理者 または 特権ユーザ
CannotManageUsersEnableManageTenant でない かつ 特権ユーザでない かつ ShowProfiles が false
CanReadCanManageTenant または 本人(UserId == Id) または EnableManageTenant
CanCreateEnableManageTenant なら false、それ以外は CanManageTenant
CanUpdateCanManageTenant または 本人 または EnableManageTenant
CanDeleteCanManageTenant かつ 本人でない
CanImportCanManageTenant
CanExportCanManageTenant または EnableManageTenant

各操作の検証の順序です(UserValidators.cs)。

操作評価順
GetValidateApi のみ
CreateValidateApi → ShowProfiles または特権ユーザ → CanCreate → 列ごとの CanCreate
UpdateValidateApi → CannotManageUsers → 自分の「テナント管理者」の変更禁止 → CanUpdate → 列ごとの CanUpdate
DeleteValidateApi → ShowProfiles または特権ユーザ → CanDelete
ImportValidateApi → ShowProfiles または特権ユーザ → CanImport

ShowProfiles(Service.json、既定 true)が false だと、特権ユーザ以外は Create・Delete・Import が InvalidRequest になり、Update も EnableManageTenant のユーザ以外は CannotManageUsers で止まります。

Get ​

API の場合、OnEntry は ValidateApi だけで通過し、CannotManageUsers やテナント管理者のチェックをしません(UserValidators.cs#L18-L43)。画面のユーザ管理(api: false)では CannotManageUsers と「テナント管理者または EnableManageTenant」を確かめるので、API と画面で入口の条件が違います。

取得結果は Users.TenantId でテナントに絞られます。メールアドレスは、リクエストのビューの ApiGetMailAddresses を指定したときだけ含まれます。ビューの ColumnFilterHash に SiteId を指定すると、そのサイトの読み取り権限を確かめたうえで、そのサイトに権限を持つ有効なユーザだけに絞られます(UserUtilities.cs#L5063-L5190)。

Update(自分のプロファイルの更新) ​

一般ユーザが自分の UserId を指定して /api/users/{id}/Update を呼ぶと、次の順に通過します。

図を読み込み中…

自分の「テナント管理者」を変える操作は PermissionNotSelfChange で拒否されますが、この判定は context.Forms.Exists("Users_TenantManager") を見ています(UserValidators.cs#L1082-L1086)。API のリクエストはフォームではなく JSON なので、API ではこのチェックは働かず、列ごとの CanUpdate だけで判定されます(「テナント管理者」の列は既定で更新に ManageTenant が必要なので、テナント管理者以外は変えられません)。

列ごとのチェックは、更新できない列について値が変わっている場合だけ HasNotChangeColumnPermission を返します。更新できない列を同じ値で送ってもエラーにはなりません。

Delete ​

CanDelete は「CanManageTenant かつ本人でない」だけで、削除対象が特権ユーザかどうかは見ません。テナント管理者は特権ユーザも削除できます(Permissions.cs#L608-L610)。対策は 拡張 SQL の活用(一覧から隠す方法)と 特権ユーザの削除・編集の制限(改修案) を参照してください。

ユーザ種別ごとの可否 ​

ShowProfiles = true(既定)で、API が使えるユーザの場合です。

操作テナント管理者一般ユーザEnableManageTenant特権ユーザ
Get可可(テナント内の全ユーザ)可可
Create可(ただし EnableManageTenant も有効なら不可)不可不可可
Update可(全ユーザ)自分だけ可(全ユーザ)可
Delete可(自分以外)不可不可可(自分以外)
Import可不可不可可

列ごとの既定のアクセス制御 ​

ユーザ管理の SiteSettings には、サイト権限の代わりに Permissions.Admins() の値(テナント管理者なら ManageTenant、サービス管理者なら ManageService のビット)がセットされます。各列の既定の条件は列定義(App_Data/Definitions/Definition_Column/Users_*.json)の ReadAccessControl・CreateAccessControl・UpdateAccessControl で、主なものは次のとおりです(1.5.8.1)。

既定の条件列
読み取り・作成・更新とも ManageTenantテナント管理者、トップサイトでの作成許可、グループ管理の許可、グループ作成の許可、API の許可、トップサイトからの移動許可、二要素認証の有効化・無効化、無効、ロックアウト、ロックアウト回数、ログイン有効期限、パスワード有効期限、シークレットキーの有効化
更新だけ ManageTenant組織(DeptId)、パスワード(読み取りは ManageService)
読み取り・作成・更新とも ManageService姓、名、生年月日、性別、姓名の順序、サービス管理者、開発者
読み取りは ManageTenant、作成・更新は ManageService最終ログイン日時、ログイン回数、認証失敗回数、パスワード変更日時
条件なし(誰でも)ログイン ID、グローバル ID、名前、ユーザコード、言語、タイムゾーン、テーマ、管理者、説明 など

「条件なし」の列は項目のアクセス制御では制限されないため、CanUpdate を通ったユーザ(本人を含む)が変更できます。ManageService が条件の列は、テナント管理者や特権ユーザでも ServiceManager でなければ読み書きできません(特権ユーザは ManageTenant のビットは持ちますが ManageService は持ちません)。

API の許可(AllowApi)の列は、User.json の DisableApi もテナントの DisableApi も false のとき(または契約で API が無効のとき)、条件が ManageService に差し替えられ、通常は見えません。パラメータかテナントで API を無効にしているときは列定義どおり ManageTenant が条件になり、委任管理のユーザに対しては条件なしに差し替えられます(SiteSettingsUtilities.cs#L536-L597)。

関連ページ ​

変更履歴

第1版管理機能の権限・グループの入れ子・トップ画面とテナント・api/users の実行権限の解説と、権限グループ・特権ユーザ保護の改修・設計メモを追加