アカウントまたはグループに権限設定して、もろもろの属性に応じたアクセス制御を行うことになった。
- システム管理者が参照・作成・更新・削除といった権限を含むロールを作成
- システム管理者がトップレベルのリソース(ルートディレクトリ的なもの)を作成
- システム管理者がトップレベルのリソースごとに管理者を指定(アカウントに管理者ロールを指定するイメージ)
- 各トップレベルリソースの管理者が、そのリソースに参加するアカウントや、複数アカウントが参加するグループにロールを割り当て
- リソース作成権限のあるロールを持ったアカウントがリソース(サブディレクトリやファイル的なもの)を作成
のような仕様になりそうで、スクラッチで実装するのは難しいと判断。
アプリケーションはJava+Spring Bootで実装しており、Javaで認可処理を行うためのOSSライブラリがないか調査したのでメモ。
Spring Security
おなじみSpring Security。
hasRole
などによるロール判定と同じように、 Spring EL式、および SecurityExpressionOperations で hasAuthority
などによる権限判定が可能。知らなかった...
hasAuthority
の使い方も hasRole
と同様、チェックしたい権限名を文字列で指定する。
ロールと権限の違いだが、先のJavadocによると、デフォルトではロールの場合は接頭語として ROLE_
が付くが、権限の場合は付かないだけの模様。これらのメソッドが GrantedAuthority
をチェックしていることを考えると、 hasRole
が hasAuthority
の特化メソッドにも思える。
以下、実装例の記載があるブログ記事。
ロールの接頭語を変更していない場合、 hasRole("USER")
を hasAuthority("ROLE_USER")
と置き換えることも可能。リファレンス中でも、hasAuthority
の引数として、 SCOPE_contacts
のように SCOPE_
を接頭語としている文字列と、ROLE_USER
のようにロールを指定している部分がある。
Apache Shiro
これまたおなじみApache Shiro。大本のJSecurityがApacheに移管されたのが2008年らしい。
Spring連携も可能、Apacheなのでライセンスは当然Apache License 2.0。
レルムなどはクラスとして実装する模様。
OpenAM
こちらもかなり以前から聞くやつ。
上記の記事によると、どうやら「ForgeRock AM」としてクローズドソース化したものと分かれており、日本ではOpenAMコンソーシアムが中心となってメンテナンスされている模様。GitHubのホストが openam-jp
だったり、日本語READMEがあるのもそのあたりの経緯からか。
OpenStandiaによると、レルムによるグループ制御やXACML (eXtensible Access Control Mark-Up Language)ベースのポリシー管理によるアクセス制御が可能とのこと。
ネックとしては、Maven CentralなどのパブリックなMavenリポジトリで公開されていないこと、またライセンスがCDDLでGPL非互換なことか。
Casbin/jCasbin
Goで実装された認可ライブラリ。認可に特化しており、認証やユーザーのパスワード管理などは行わない。
様々なプログラミング言語に移植されており、Java移植版がjCasbin。Mavenリポジトリでも公開されている。
ライセンスはApache License 2.0。
また、ミドルウェアとして、Spring BootやApachi Shiroと統合し、それらの認可をCasbinに移譲できる模様(それぞれ2~3種類あるが)。Spring Bootを利用しているのであれば、casbin-spring-boot-starterを使うのが手っ取り早いか。
アクセス制御モデルは、PERM(Policy, Effect, Request, Matchers)に基づいた設定ファイルに保存する。それとは別にポリシーを保存しておき、それぞれ読み込んで Enforcer
を生成する模様。
ポリシー保存先に応じたアダプターが実装されており、Javaでは組み込みのCSVファイル以外に、JDBC、Hibernate、MyBatis、DynamoDB、Redisなど利用可能。
特徴的な点として、アクセス制御モデルとポリシーのテストができるオンラインエディターが用意されている。
番外: Keycloak
認証および認可を行う、Red HatがサポートしているOSS。
getting-started によると、Java実行環境(OpenJDK)、Docker、k8s、またRed HatなのでPodmanでもサーバーとして起動できる模様。また、Vue.jsからも利用できるとのこと。
軽く調べてみた限り、どうもライブラリとしてアプリケーションに組み込んだりはできず、サーバーとして起動しておいてAPIを叩いたりするものらしい。
JavaやJavaScript用のアダプターはあるようだが、今回は既存のアプリケーションに組み込む前提なので、対象外とした。
振り返り
Spring Securityで権限判定ができることが分かったのが大きい。Spring Bootが支配的な最近のJava環境では、Spring Security+AOPで実装できるのはありがたい。
文字列ベースでは厳しい複雑な権限制御が必要になるのであれば、Apache ShiroやjCasbinに認可実装を委譲することもできそう。
また、今回は既存のアプリケーションを拡張する必要があるため、ライブラリとして導入できるものを調べたが、Amazon Cognitoのようなマネージドサービスに認証/認可を任せてしまうのがいいのだろう。
なお、権限設定の設計については、以下のページが参考になった。