権限設定を実装するため、Javaで使える認可ライブラリについて調べた

アカウントまたはグループに権限設定して、もろもろの属性に応じたアクセス制御を行うことになった。

  1. システム管理者が参照・作成・更新・削除といった権限を含むロールを作成
  2. システム管理者がトップレベルのリソース(ルートディレクトリ的なもの)を作成
  3. システム管理者がトップレベルのリソースごとに管理者を指定(アカウントに管理者ロールを指定するイメージ)
  4. 各トップレベルリソースの管理者が、そのリソースに参加するアカウントや、複数アカウントが参加するグループにロールを割り当て
  5. リソース作成権限のあるロールを持ったアカウントがリソース(サブディレクトリやファイル的なもの)を作成

のような仕様になりそうで、スクラッチで実装するのは難しいと判断。

アプリケーションはJava+Spring Bootで実装しており、Javaで認可処理を行うためのOSSライブラリがないか調査したのでメモ。

Spring Security

おなじみSpring Security

hasRole などによるロール判定と同じように、 Spring EL式、および SecurityExpressionOperationshasAuthority などによる権限判定が可能。知らなかった...

hasAuthority の使い方も hasRole と同様、チェックしたい権限名を文字列で指定する。

ロールと権限の違いだが、先のJavadocによると、デフォルトではロールの場合は接頭語として ROLE_ が付くが、権限の場合は付かないだけの模様。これらのメソッドが GrantedAuthority をチェックしていることを考えると、 hasRolehasAuthority の特化メソッドにも思える。

以下、実装例の記載があるブログ記事。

www.kimullaa.com

ロールの接頭語を変更していない場合、 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

github.com

こちらもかなり以前から聞くやつ。

qiita.com

上記の記事によると、どうやら「ForgeRock AM」としてクローズドソース化したものと分かれており、日本ではOpenAMコンソーシアムが中心となってメンテナンスされている模様。GitHubのホストが openam-jp だったり、日本語READMEがあるのもそのあたりの経緯からか。

OpenStandiaによると、レルムによるグループ制御やXACML (eXtensible Access Control Mark-Up Language)ベースのポリシー管理によるアクセス制御が可能とのこと。

ネックとしては、Maven CentralなどのパブリックなMavenリポジトリで公開されていないこと、またライセンスがCDDLGPL非互換なことか。

Casbin/jCasbin

casbin.org

Goで実装された認可ライブラリ。認可に特化しており、認証やユーザーのパスワード管理などは行わない。

様々なプログラミング言語に移植されており、Java移植版がjCasbinMavenリポジトリでも公開されている。

ライセンスは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ファイル以外に、JDBCHibernate、MyBatis、DynamoDB、Redisなど利用可能。

特徴的な点として、アクセス制御モデルとポリシーのテストができるオンラインエディターが用意されている。

番外: Keycloak

www.keycloak.org

認証および認可を行う、Red HatがサポートしているOSS

getting-started によると、Java実行環境(OpenJDK)、Docker、k8s、またRed HatなのでPodmanでもサーバーとして起動できる模様。また、Vue.jsからも利用できるとのこと。

軽く調べてみた限り、どうもライブラリとしてアプリケーションに組み込んだりはできず、サーバーとして起動しておいてAPIを叩いたりするものらしい。

JavaJavaScript用のアダプターはあるようだが、今回は既存のアプリケーションに組み込む前提なので、対象外とした。

振り返り

Spring Securityで権限判定ができることが分かったのが大きい。Spring Bootが支配的な最近のJava環境では、Spring Security+AOPで実装できるのはありがたい。

文字列ベースでは厳しい複雑な権限制御が必要になるのであれば、Apache ShiroやjCasbinに認可実装を委譲することもできそう。

また、今回は既存のアプリケーションを拡張する必要があるため、ライブラリとして導入できるものを調べたが、Amazon Cognitoのようなマネージドサービスに認証/認可を任せてしまうのがいいのだろう。

なお、権限設定の設計については、以下のページが参考になった。

kenfdev.hateblo.jp