アノテーションを使用した JAX-RS リソースの保護
セキュリティー設定を指定するアノテーションを使用して、 Java™ API for RESTful Web Services (JAX-RS) リソースを保護できます。
始める前に
このタスクでは、既にアプリケーションを開発しており、セキュリティーに関するアノテーションを使用して保護する JAX-RS リソースを特定済みであることを前提としています。
このタスクについて
- @PermitAll - すべてのセキュリティー・ロールに JAX-RS リソースへのアクセスを許可することを指定します
- @DenyAll - すべてのセキュリティー・ロールに JAX-RS リソースへのアクセスを許可しないことを指定します
- @RolesAllowed - JAX-RS リソースへのアクセスを許可するセキュリティー・ロールを指定します
クラス・レベルでアノテーションを付けるか、またはメソッド・レベルでアノテーションを付ける かを選択できます。セキュリティーに関するアノテーションには、以下のルールが適用されます。
- メソッド・レベルのアノテーションは、クラス・レベルのアノテーションに優先します。
- 以下のコード・スニペットで、/addresses @GET アノテーションと @Path アノテーション、および対応する getList() メソッドの @GET アノテーションと @Path アノテーションにより参照される JAX-RS リソースは、制限されておらず、ロールにかかわらず使用できます。 しかし、/addresses の @GET アノテーションと @Path アノテーション、および対応する updateList() メソッドの @PUT アノテーションと @Path アノテーションにより参照されるリソースは、Manager ロールを必要とします。以下に例を示します。
@Path(value="/addresses") @PermitAll public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } @PUT @RolesAllowed(“Manager”) to public void updateList(String[] books) { } }
- セキュリティーに関するアノテーションは互いに排他的です。
- これは、各リソースについて、セキュリティーに関するアノテーションは 1 つまでしか使用できないことを意味します。例えば、以下の例は、@PermitAll アノテーションと @RolesAllowed アノテーションが指定されているため、無効になります。
@Path(value="/addresses") @PermitAll @RolesAllowed(“Employee”) public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } }
上記のコード例では、@RolesAllowed アノテーションが優先され、 @PermitAll アノテーションは無視されます。 同様に、@RolesAllowed アノテーションと @DenyAll アノテーションが指定されると、 @DenyAll アノテーションが優先されます。
また、 @PermitAll アノテーションと @DenyAll アノテーションがメソッド・レベルまたはクラス・レベルで 指定されると、安全なデフォルトの原則に従ってセキュリティーを保証するために @DenyAll アノテーションが優先されます。
@PermitAll、@DenyAll および @RolesAllowed のすべてのアノテーションが メソッド・レベルまたはクラス・レベルにある場合、@DenyAll アノテーションが @RolesAllowed アノテーションおよび @PermitAll アノテーションに優先します。このアノテーションの優先順位は以下のとおりです。- @DenyAll
- @RolesAllowed
- @PermitAll
- 継承のルール
- クラス・レベルで追加された JSR 250 アノテーションは、 そのアノテーションを付けたクラス、およびサブリソースの対応するメソッドにのみ作用します。 クラス・レベルで指定されたアノテーションは、スーパークラスから継承したリソースには作用しません。
- メソッドのオーバーライドのルール
- サブクラスでオーバーライドされたメソッドに対応するリソースのアノテーションは、
親クラスに含まれるアノテーションに優先します。例えば、以下のスニペットでは、
/addresses/local サブリソースへのアクセスに LocalAdministrator ロールが使用されます。
s@Path(value="/addresses") @PermitAll public class AddressBookResource { @GET @Produces(value="text/plain") public String getList() { } @PUT @RolesAllowed(“Administrator”) public void updateList(String books) { } } @Path(value="/addresses") @PermitAll public class LocalAddressBookResource extends AddressBookResource { @PUT @RolesAllowed(“LocalAdministrator”) @Path(value=”local”) public void updateList(String books){ } }
- @RolesAllowed の考慮事項
- 1 つのリソースに同時に複数の @RolesAllowed アノテーションを使用することはできません。
例えば、以下のようにしたい場合は、
以下のようなコード・スニペットを使用します。@RolesAllowed("role1") @RolesAllowed("role2") public String foo() { }
@RolesAllowed({"role1", "role2"}) public String foo() { }
- セキュリティーに関するアノテーションの使用およびセキュリティー制約の構成についての考慮事項
セキュリティーに関するアノテーションは、宣言セキュリティー・モデルに従います。 デプロイメント記述子 (web.xml ファイル) で構成されているセキュリティー制約は、アプリケーションにおいてプログラムでアノテーションにより設定されているセキュリティー制約に優先します。JAX-RS リソースの開発者は、構成可能なセキュリティー制約とアノテーションによるセキュリティー制約の バランスを考慮する必要があります。アノテーションによる制約は、 構成されたセキュリティー制約の付加的なものです。 JAX-RS ランタイム環境は、web.xml ファイル内に構成されているセキュリティー制約を Web コンテナー・ランタイム環境が 検査した後、アノテーションによる制約を検査します。
認証制約を web.xml ファイル内に構成します。 以下の web.xml ファイルの例では、SecurityConstraint_1 セキュリティー制約が 定義されています。この制約は、アプリケーションに対する認証を要求するために使用されます。 また、SecurityConstraint_1 セキュリティー制約は、 JAX-RS リソースに対応する URL パターンに関する制約を定義しています。 これらの制約のいずれかに相当する JAX-RS リソースにアクセスすると、 許可検査が行われます。アクセス権限の検査は、構成されている制約が検証された後で、 宣言セキュリティー・アノテーションに対して行われます。<web-app id="WebApp_someID"> <servlet> <servlet-name>AddressBookAppSample</servlet-name> <servlet-class> org.apache.wink.server.internal.servlet.RestServlet </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>jaxrs.sample.AddressBookApplication </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AddressBookApp</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <security-constraint id="SecurityConstraint_1"> <web-resource-collection id="WebResourceCollection_1"> <web-resource-name>AddressBookAppSample</web-resource-name> <description>Protection area for Rest Servlet</description> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint id="AuthConstraint_1"> <description>Role1 for this rest servlet</description> <role-name>Role</role-name> </auth-constraint> <user-data-constraint id="UserDataConstraint_1"> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-role id="SecurityRole_1"> <description>This Role is used to drive authentication </description> <role-name>Role1</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>test realm</realm-name> </login-config> </login-config> </web-app>
上記のサンプル web.xml ファイルで、Role1 がアプリケーション全体に使用されています。 宣言セキュリティー・アノテーションのみを定義し、web.xml ファイルによる許可制約を使用しない場合は、 JAX-RS アプリケーションに対するこのロールをユーザー認証用の AllAuthenticated 特殊サブジェクトにマップすることができます。
手順
- JAX-RS アプリケーションに対して web.xml ファイルで定義するセキュリティー制約があるかどうかを確認します。
- web.xml ファイルを構成して、セキュリティー制約を追加します。 デプロイメント記述子 (web.xml ファイル) で構成されているセキュリティー制約は、 アプリケーションにおいてプログラムでアノテーションにより設定されているセキュリティー制約に優先します。
- web.xml ファイルで定義される制約のほかに、セキュリティーに関するアノテーションを追加するかどうかを確認します。 @PermitAll、@DenyAll、@RolesAllowed のいずれかのアノテーションを追加して、 JAX-RS リソースに追加のセキュリティーを指定するかどうかを決めます。 セキュリティーに関するアノテーションを追加する際のルール (前述の優先や継承などに関するルール) を 考慮してください。
タスクの結果
宣言セキュリティー・アノテーションを使用して、セキュアな JAX-RS リソースを定義しました。
例
@Path(value="/addresses")
@PermitAll
public class AddressBookResource {
@GET
@Produces(value="text/plain")
public String getList() {
}
@RolesAllowed(“Administrator”)
@PUT
public void updateList(String books) {
}
}