Java Enterprise Edition Version 6 (JEE6) リリースには、webコンテナ の領域における、新しいセキュリティ フィーチャが、Javaアプリケーション開発における、認証と認可の側面と共に含まれている。これらのフィーチャには、web層における、プログラムによるセキュリティ強化と宣言型のセキュリティ強化が含まれている。
Servlet 3.0仕様書 (JSR 315)に基づいて、 Java EE 6 Webアプリケーションは、新しいプログラム的そして宣言型 なセキュリティ フィーチャとEJB 3.x アプリケーションに以前から使えた Securityアノテーションを利用できる。webアプリケーションは、サーブレット・コンテナの一部として構成できる、 JSR 196 ベースのプラグイン可能な認証/認可モジュールを使うこともできる。
Webモジュール セキュリティ
Webモジュール セキュリティは、プログラム( HTTP Servlet Requestに加わった新しいセキュリティ メソッドを使って)でも、宣言的な方法(新しいセキュリティ アノテーションを使って)でも実装できる。
プログラムによるセキュリティ
コンテナ セキュリティのコンテキストには、 HTTP Servlet Requestに加わった新しいセキュリティ メソッドを使って、プログラムでアクセスできる。 Servlet 3.0は、webアプリケーションでユーザを認証するのに使える、HttpServletRequest interface の以下のメソッドを定義している。
- authenticate: このメソッドは、コンテナのログイン メカニズムを使っている。これは、ServletContextが認証を要求しているユーザを認証するためのものである。
- login: このメソッドは、webコンテナによって使われているセキュリティレルムで与えられたユーザ名とパスワードを検証する。アプリケーションのディプロイメント デスクリプタ(配置記述子)内のフォームベースの認証を特定する代替として、アプリケーションがユーザ名とパスワードの情報を取得するのに使用できるが、開発者が認証プロセスをプログラムで、制御できるようにもしている。
- logout: このメッソドによって、リクエストの際にgetUserPrincipal、 getRemoteUser そしてgetAuthTypeのような他のメソッドが 呼ばれる時に、webアプリケーションが、リクエストしている呼び出し側IDをリセットし、返り値としてnullを返すことができるわけである。
以下のHttpServletRequest interface メソッドも、コンポーネントの呼び出し側のセキュリティ情報にアクセスするために使うことができる:
- getRemoteUser: このメソッドは、クライアント認証を受けたユーザ名を取得するために呼ばれる。このメソッドは、コンテナによって、リクエストと結び付いたリモートのユーザ名を返す。もし誰も認証されていなければ、nullを返す。
- isUserInRole: このメソッドは、リモートのユーザがある特定のセキュリティロール内にあるかどうかを確定する。もし誰も認証されていなければ、falseを返す。このメソッドは、String 型のrole-name(ロール名)をパラメータとして取る。security-role-ref 要素は、メソッドに渡されるロール名を持つ role-nameサブ要素といっしょに、ディプロイメント デスクリプタ内で宣言されるべきである。
- getUserPrincipal: このメソッドは、現在のユーザのプリンシパル名 を確定する時に呼ばれ、java.security.Principal オブジェクトを返す。もし誰も認証されていなかったら、nullを返す。このメソッドによって返された Principalオブジェクトに、 getNameメソッドを呼べば、リモートのユーザ名が返される。
宣言型セキュリティ
webモジュールのセキュリティを強化するために,使うことができる新しいアノテーションがある。与えられたアノテーションとディプロイメント デスクリプタを使って、認証、認可そしてトランスポート レベルの暗号化を利用することができる:
- @ServletSecurity: サーブレットの実装クラスに、 @ServletSecurity を使うと、HTTPプロトコルメッセージで、サーブレットコンテナによって強制される、セキュリティ制限を指定できる。サーブレット コンテナは、サーブレットにマップされたURLパターンで、これらの制限を強制できる。
- @HttpMethodConstraint: The @HttpMethodConstraint アノテーションを使うと、 ServletSecurityアノテーション内で、特定のHTTPプロトコル メッセージに対する、セキュリティ制限を表すことができる。
- @HttpConstraint: この アノテーション を使うと、 ServletSecurityアノテーション内で、対応する HttpMethodConstraint要素が指定されていない、全HTTPメソッドを保護するように、セキュリティ制限を課すことができる。
- @DeclareRoles:@DeclareRoles は、クラス レベルのアノテーションで、Common Annotations 1.0 (JSR 250) 仕様書の一部で、アプリケーションで使用される役割を定義する際にsecurity-role 要素のように振舞う。
- @RunAs:@RunAsアノテーションも Common Annotations 1.0の一部で、あるコンポーネントのrun-as ロールを指定する。エンタプライズbeanの特定のメソッドを実行するために,使用すべき、呼び出し側のセキュリティIDか、あるいは、特定の run-as IDを使うべきかを指定することができる。このアノテーションもクラス スコープである。
もしwebアプリケーションがサーブレットからできているなら、セキュリティ制限を指定するのには、@ServletSecurityアノテーション内の@HttpConstraint と、オプションで、@HttpMethodConstraintアノテーションを使うのがいい。他のwebアプリケーションでは、ディプロイメント デスクリプタで security-constraint要素を使うことになる。
セキュリティ ロールを宣言する
セキュリティ ロールの名前は、ディプロイメント デスクリプタのsecurity-role要素を使って宣言できる。セキュリティ ロール参照は、isUserInRole(String role)を使って、webコンポーネントから呼ばれるロールの名前とアプリケーション用に定義されたセキュリティ ロールの名前との間のマッピングを定義している。例えば、セキュリティ ロール参照 "cust" をロール名 "bankCustomer"を持ったセキュリティ ロールにマップするには、シンタックスは次のようになる:
<servlet> ... <security-role-ref> <role-name>cust</role-name> <role-link>bankCustomer</role-link> </security-role-ref> ... </servlet>
もしサーブレットが "bankCustomer" セキュリティ ロールに属するユーザによって呼ばれれば、メソッド呼び出しisUserInRole("cust")がtrueを返す。 security-role-ref要素の role-link要素は、以下に示すような、同じweb.xml ディプロイメント デスクリプタのsecurity-role 要素中に定義されている role-nameとマッチしなけばならない。:
<security-role> <role-name>bankCustomer</role-name> </security-role>
トランスポート セキュリティを強制する
トランスポート セキュリティは、クライアントに送られているデータあるいは、クライアントから受け取ったデータが,誰にも改ざんできないことを保証する。JavaEEの仕様は、web.xml ファイルの"user data constraint" と "transport guarantee"要素を使って、あるいは、HttpConstraint アノテーションの "transportGuarantee" 特性を使って、開発者が、トランスポート セキュリティを強制できるようにしている。保護されたトランスポート層のコネクションを介して、制約されたリクエストが受信される,という要求をユーザデータの制約は、確立する。要求された保護の強さは、 transport guaranteeの値によって決められる。以下が、 TransportGuarantee 内部クラスよって定義された値である:
- CONFIDENTIAL: このtransport guarantee 要素は、コンテンツの必要な部分に、機密性の要求を行うために使用される。データは暗号化されるので、第3者によって、解読できないことを保証する。
- NONE: このtransport guaranteeレベルは、SSLを適用せずに、通常のデータ転送を実行する。そのため、コンテナは、保護されていないコネクションを含めていかなるコネクションで受信する時も、制約されたリクエストを受け入れなければならない、ことになる。
トランスポート保護が必要なリソースを持っている場合、web.xml 内のsecurity-constraint タグの中に置かれるべきである "user-dataconstraint" 要素を使って、トランスポート セキュリティを強制できる。
<user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint>
Java EE 6のセキュリティ フィーチャをもっと詳しく知りたければ、 Servlet 3.0 仕様書(第13章)と Java EE 6チュートリアル (第24章)のセキュリティに関する章を調べて欲しい。 DZone も最近、 Java EEのセキュリティ強化に関する reference card を公表した(注:彼らのwebサイトからドキュメントをダウンロードするには、登録が必要である)。