Apache Shiroのチュートリアルの一部でアーキテクチャ概要に関する部分の https://shiro.apache.org/architecture.html をテキトーに訳した。
Apache Shiro Architecture
Apache Shiroの設計目標は直感的で使いやすいようにアプリケーションセキュリティを単純化することです。Shiroのコア部分の設計は、人がアプリケーションセキュリティをどう捉えるかをモデル化しており、そのモデルはアプリケーションと相互作用する誰か(もしくは何か)という状況を背景に置いています。
通常、ソフトウェアアプリケーションはユーザーストーリーに沿って設計されます。つまり、開発者は、ユーザとソフトウェアが相互作用する(もしくは、すべき)方法に従って、ユーザインタフェースもしくはサービスAPIを設計していると思います。たとえば、"アプリケーションと相互作用するユーザはログイン後、そのユーザ自身のアカウント情報を参照可能なクリックできるボタンを表示する。未ログインの場合、サインアップボタンを表示する。"といった具合です。
上記の例文は、アプリケーションは主としてユーザ要求とニーズを満たすように作られる、ということを示しています。"ユーザ"が別システムの場合や、人間ではない場合でも、ソフトウェアがある時点で相互作用する誰か(もしくは、何か)を基点にした振る舞い を反映するようなコードを開発者は作成します。
Shiroはこうした思想を設計に組み込んでいます。開発者にとって直感的な概念に合わせることにより、Apache Shiroは直感的であらゆるアプリケーションに実用的な使いやすさを提供しています。
High-Level Overview
最上位の設計レベルにおいて、Shiroのアーキテクチャは三つの主要な概念、Subject
, SecurityManager
, Realms
で構成されています。以下の図はそれらのコンポーネントの相互作用の概要を示しています。各コンポーネントについては後で解説します。
図:https://shiro.apache.org/assets/images/ShiroBasicArchitecture.png
- サブジェクト(Subject): チュートリアルにある通り、
Subject
は基本的に現在実行中ユーザのセキュリティ視点での'ビュー(view)‘となります。'ユーザ(User)'という単語は人間を連想させますが、Subject
は人間以外に、サードパーティのデバイス、デーモンアカウント、cron jobなどが考えられ、要するにソフトウェアとその時相互作用する何か、になります。
Subject
インスタンスはすべてSecurityManager
にバインドされています*1。Subject
と相互作用するとき、その相互作用はSecurityManager
を用いるサブジェクト固有の相互作用に変換されます。 - セキュリティマネージャー(SecurityManager):
SecurityManager
はShiroのアーキテクチャの中核で、ある種のアンブレラ(‘umbrella’)オブジェクトとして振る舞います。このオブジェクトは、内部的なセキュリティコンポーネントとの調整役となり、コンポーネントと共にオブジェクトグラフを形成しています。ただし、SecurityManagerと内部オブジェクトグラフを一度アプリケーションに設定したあとは、基本的にその設定を触ることは無く、アプリケーション開発者はSubject
API以外を使うことはほとんどありません。
SecurityManager
に関する詳細は後ほど触れますが、Subject
と何らかの相互作用を行う場合、Subject
のあらゆるセキュリティ操作に対する、すべての重い処理の背後には実際にはSecurityManager
がいることを覚えておいて下さい。この処理の流れは上の図の通りです。 - Realms(レルム): レルムの振る舞いはShiroとアプリケーションのセキュリティデータ間で"ブリッジ"あるいは"コネクタ"といったものになります。認証(ログイン)と認可(アクセス制御)の実行にユーザアカウントなどのセキュリティ関連データを用いて実際に相互作用する段階になると、Shiroはアプリケーションに設定されている一つ以上のレルムから様々なデータを参照します。
その意味において、レルムは基本的にはセキュリティ固有のDAOと言えます。このDAOは、データソースへの接続詳細をカプセル化し、必要に応じて関連データをShiroで利用可能にします。Shiroの設定時には、認証もしくは認可の両方で使うためのレルムを少なくとも一つ指定する必要があります。SecurityManager
は複数のレルムを設定可能で、少なくとも一つのレルムが必要です。
Shiroはいくつかのレルムを提供しており、LDAP, RDB(JDBC), INIライクのテキスト設定ソース, プロパティファイルなどのセキュリティデータソースに接続するためのレルムを用意しています。これらデフォルトのレルムが要求を満たさない場合、カスタムデータソースを記述する自前のレルム実装をプラグイン出来ます。
他の内部コンポーネント同様に、ShiroのSecurityManager
は、Subject
に用いられるアイデンティティデータとセキュリティデータを取得するのに使われるレルムを管理します。
Detailed Architecture
以下はShiroのコアアーキテクチャを示す図です。
図:https://shiro.apache.org/assets/images/ShiroArchitecture.png
以下は個々の要素の概要です。
- Subject(org.apache.shiro.subject.Subject))
セキュリティ視点でのエンティティ(ユーザ・サードパーティサービス・cron・jobなど)の'ビュー'で、ソフトウェアと相互作用を行う。 - SecurityManager(org.apache.shiro.mgt.SecurityManager)
上述のように、SecurityManager
はShiroのアーキテクチャの中核要素です。SecurityManagerは基本的には配下の管理コンポーネント群をうまいこと動作させるための詳細を隠蔽しています。また、アプリケーションユーザごとのShiroのビューを管理しており、ユーザごとに必要となるセキュリティ操作も管理しています。 - Authenticator(org.apache.shiro.authc.Authenticator)
Authenticator
はユーザの認証(ログイン)要求に対する処理と反応を返すためのコンポーネントです。ユーザがログインをするとき、そのロジックはAuthenticator
が実行します。Authenticator
はユーザ/アカウント関連情報を格納している一つ以上のRealms
の処理を担っています。Realms
から取得するデータは、そのユーザが自分自身を誰だと言ってきているのかを保証するユーザ一意性(user’s identity)を検証するのに使われます。- Authentication Strategy (org.apache.shiro.authc.pam.AuthenticationStrategy)
複数のRealm
を設定する場合、AuthenticationStrategy
は認証処理の成功と失敗を決定するためにRealms間の調整を行います(たとえば、もし一つのレルムが成功して他は失敗の場合、認証処理は成功とするのか? すべてのレルムが成功しなければならないのか? 最初のみ成功でも通すのか?)。
- Authentication Strategy (org.apache.shiro.authc.pam.AuthenticationStrategy)
- SessionManager (org.apache.shiro.session.mgt.SessionManager)
SessionManager
は、Sessionに関する堅牢なユーザ体験をあらゆる環境下で提供するため、ユーザSession
ライフサイクルの作成と管理を担当します。セキュリティフレームワーク界隈においてこれはユニークな機能で、Web/ServletやEJBコンテナが利用可能でなくとも、Shiroはどんな環境でもユーザのSessionを管理する能力を有しています。デフォルトでは、Shiroは何らかの機構(Servletコンテナなど)が使えればそのセッション機構を使用しますが、それが無い場合、たとえばスタンドアローンアプリケーションや非web環境などでは、何らかの機構と同様の体験を提供するのにShiroに組み込まれているエンタープライズセッション管理を使用します。SessionDAO
は何らかのデータソースがセッションを永続化するのを許可するために使います。- SessionDAO (org.apache.shiro.session.mgt.eis.SessionDAO)
SessionDAO
はSession
の永続化(CRUD)操作を実行するためのSessionManager
とのインタフェースです。このクラスを使うことで任意のデータストアをセッション管理インフラに組み込めます。
- SessionDAO (org.apache.shiro.session.mgt.eis.SessionDAO)
- CacheManager (org.apache.shiro.cache.CacheManager)
CacheManager
はShiroのコンポーネントが使用するCache
インスタンスのライフサイクルの生成と管理を行います。Shiroは多数のバックエンドデータソースにアクセスして認証・認可・セッション管理を行うため、キャッシュはフレームワーク内で主要機能であり、それらのデータソースを使用する場合のパフォーマンスを向上させるために存在します。高速かつ効果的なユーザ体験を提供するために、Shiroには最近のオープンソースまたはエンタープライズのキャッシュプロダクトを組み込むことが可能です。 - Cryptography (org.apache.shiro.crypto.*)
暗号化はエンタープライズのセキュリティフレームには当然存在してしかるべきものです。Shiroのcrypto
パッケージには理解しやすく使いやすい暗号・ハッシュ(ダイジェスト)・コーデック実装が含まれています。このパッケージのすべてのクラスは使いやすく理解しやすくなるよう特に注意を払って設計されています。Javaの暗号化サポートを知る人であれば、野獣の調教に挑むような経験をしているでしょう。Shiroの暗号化APIは複雑なJavaのメカニズムを単純化して一般的な人類*2にとって使いやすい形にしています。 - Realms (org.apache.shiro.realm.Realm)
上述の通り、レルムはShiroとアプリケーションデータ間の'ブリッジ'あるいは'コネクタ'として振る舞います。認証(ログイン)と認可(アクセス制御)を処理するのにユーザアカウントなどのセキュリティ関連データと相互作用する段階になると、Shiroはアプリケーションに設定されている一つ以上のレルムから各種データを参照します。必要な数(通常はデータソースごとに一つ)のRealms
を設定可能で、Shiroは必要に応じて認証と認可でレルムを使用します。
The SecurityManager
ShiroのAPIはSubject
中心のプログラミングアプローチを取っているため、SecurityManager
を直接触るのは、無くは無いですが、滅多にありません(ただしフレームーワーク開発者は直接SecurityManagerを見るのが良い場合があります)。しかし、SecurityManager
の動きを知ることは重要で、アプリケーションでこれを設定する場合には特に重要です。
Design
前述のとおり、アプリケーションのSecurityManager
はセキュリティ操作を実行し、すべてのアプリケーションユーザの状態管理を行います。ShiroのデフォルトSecurityManager
実装には以下が含まれます。
- 認証(Authentication)
- 認可(Authorization)
- セッション管理(Session Management)
- キャッシュ管理(Cache Management)
- レルム間調整(Realm coordination)
- イベント伝播(Event propagation)
- ‘Remember Me'サービス('Remember Me’ Services)
- サブジェクト生成(Subject creation)
- ログアウトなど(Logout and more)
なお、上記の機能の多くは単一コンポーネントを管理しやすくするための機能です。また、単一の実装クラスにすべてを詰め込もうとすると、柔軟性を持たせてカスタマイズしやすくするのは難しくなります。
設定/プラグインを柔軟にして単純化するため、Shiroの実装は設計に高いモジュール性を設けています。このモジュール性により、SecurityManagerの実装(とそのクラス階層)がすべての処理を行うわけではありません。一枚岩にする代わりに、SecurityManager
実装はいわゆるライトウェイトな'コンテナ'コンポーネントの振る舞いをし、ネストないしラップするコンポーネントに多くの振る舞いをデリゲートします。この'ラッパー'設計は上述のDetailed Architectureの図にある通りです。
デリゲート先のコンポーネントが実際にロジックを実行するので、SecurityManager
の実装は、何らかの振る舞いを行うコンポーネントをいつ・どのように実行するか、に責任を持ちます。
SecurityManager
の実装はJavaBeans互換のため、JavaBeans標準のgetter/setterメソッドでプラガブルなコンポーネントを簡単にカスタマイズできます。Shiroアーキテクチャのモジュール性は振る舞いをカスタマイズするための設定容易性に表れています。
Easy Configuration
JavaBeans互換のため、JavaBeansスタイルの設定をサポートするSpring, Guice, JBossなどで、カスタムコンポーネントによるSecurityManagerの設定を簡単に行えます。
設定については次のConfigurationを参照してください。
Lend a hand with documentation
Apache Shiroで何かを作る際にこのドキュメントが役に立つことを願いますが、コミュニティが成長すればドキュメントも常に拡張していきます。もしShiroプロジェクトに興味がある場合、必要だと感じたドキュメントの追加・修正・収集をお願いしたいと思います。ほんの少しの助けであってもコミュニティは前進し、結果としてShiroも前進します。
ドキュメントをコントリビュートする最も簡単な方法はこのページ下のEditリンクをクリックしてプルリクエストをサブミットするか、User ForumあるいはUser Mailing Listに送信します。