この章では、Java API for RESTful Web Services (JAX-RS)を使用して、Representational State Transfer (REST)アーキテクチャ・スタイルに従ったWebLogic Webサービスを保護する方法について説明します。
この章の内容は以下のとおりです。
認証、認可または暗号化をサポートするための次のいずれかのメソッドを使用して、RESTful Webサービスを保護できます。
セキュリティ構成を定義するためのweb.xmlデプロイメント記述子の更新。「web.xmlを使用したRESTful Webサービスの保護」を参照してください。
セキュリティをプログラム的に実装するためのjavax.ws.rs.core.SecurityContextインタフェースの使用。「SecurityContextを使用したRESTful Webサービスの保護」を参照してください。
JAX-RSクラスへのアノテーションの適用。「アノテーションを使用したRESTful Webサービスの保護」を参照してください。
リクエストを署名および検証するためのJersey OAuthライブラリの使用。OAuthライブラリの使用およびインストールの詳細は、Jersey and OAuthのwiki (https://wikis.oracle.com/display/Jersey/OAuth)を参照してください。
web.xmlデプロイメント記述子を他のJava EE Webアプリケーションと同様に使用して、RESTful Webサービスを保護します。詳細は、『Oracle WebLogic Serverセキュリティのプログラミング』の安全なWebアプリケーションの開発に関する項を参照してください。
たとえば、基本認証を使用してRESTful Webサービスを保護するには、次のステップを実行します。
保護する予定のRESTfulリソース(URI)の各セットについて<security-constraint>を定義します。
<login-config>要素を使用して、使用する認証のタイプとセキュリティ制約が適用されるセキュリティ・レルムを定義します。
<security-roleタグを使用して1つ以上のセキュリティ・ロールを定義し、ステップ1で定義されたセキュリティ制約にマッピングします。詳細は、『Oracle WebLogic Serverセキュリティのプログラミング』のsecurity-roleに関する項を参照してください。
暗号化を有効にするには、<user-data-constraint要素を追加して<transport-guaranteeサブ要素をCONFIDENTIALに設定します。詳細は、『Oracle WebLogic Serverセキュリティのプログラミング』のuser-data-constraintに関する項を参照してください。
詳細は次のとおりです。
例5-1 基本認証を使用したRESTful Webサービスの保護
<web-app>
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Orders</web-resource-name>
<url-pattern>/orders</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>default</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
</web-app>
javax.ws.rs.core.SecurityContextインタフェースはリクエストのセキュリティ関連情報に対するアクセスを提供します。SecurityContextはjavax.servlet.http.HttpServletRequestと同様の機能を提供して、次のセキュリティ関連情報へのアクセスを可能にします。
リクエストを作成したユーザーの名前が含まれるjava.security.Principalオブジェクト。
リソースの保護に使用される認証タイプ(BASIC_AUTH、FORM_AUTH、CLIENT_CERT_AUTHなど)。
認証されたユーザーが特定のロールに含まれているかどうか。
リクエストが安全なチャネル(HTTPSなど)を使用して作成されたかどうか。
javax.ws.rs.core.Contextアノテーションを使用してインスタンスをクラス・フィールド、セッター・メソッドまたはメソッド・パラメータに注入することで、SecurityContextにアクセスします。
詳細は次のJavadocを参照してください。
SecurityContextインタフェース: http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/SecurityContext.html
@Contextアノテーション: http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/Context.html
図5-0に、@Contextアノテーションを使用してSecurityContextのインスタンスをscメソッド・パラメータに注入し、レスポンスを返す前に認可されたユーザーがadminロールに含まれているかどうかを確認する方法を示します。
例5-2 SecurityContextを使用したRESTful Webサービスの保護
package samples.helloworld; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.Context; ... @Path("/stateless") @Stateless(name = "JaxRSStatelessEJB") public class StlsEJBApp { ... @GET @Produces("text/plain;charset=UTF-8") @Path("/hello") public String sayHello(@Context SecurityContext sc) { if (sc.isUserInRole("admin")) return "Hello World!"; throw new SecurityException("User is unauthorized."); }
javax.annotation.securityパッケージは、表5-1で定義されている、RESTful Webサービスの保護に使用できるアノテーションを提供します。詳細は、Javadoc (http://docs.oracle.com/javaee/6/api/index.html?javax/annotation/security/package-summary.html)を参照してください。
表5-1 RESTful Webサービスを保護するためのアノテーション
| アノテーション | 説明 |
|---|---|
|
|
ロールを宣言します。 |
|
|
特定のメソッドがどのセキュリティ・ロールでも呼び出せないことを指定します。 |
|
|
特定のメソッドがすべてのセキュリティ・ロールで呼び出せることを指定します。 |
|
|
アプリケーション内のメソッドを呼び出すことができるセキュリティ・ロールのリストを指定します。 |
|
|
J2EEコンテナでの実行中にアプリケーションのIDを定義します。 |
図5-0に、helloWorldクラスに定義されたメソッドへのアクセスを、デフォルトで許可されているセキュリティ・ロールの定義方法を示します。sayHelloメソッドは、デフォルトを上書きし、ADMINセキュリティ・ロールに属すユーザーのみを許可するために、@RolesAllowsアノテーションが付けられます。
例5-3 SecurityContextを使用したRESTful Webサービスの保護
package samples.helloworld; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.annotation.Security.RolesAllowed; @Path("/helloworld") @RolesAllowed({"ADMIN", "ORG1"}) public class helloWorld { @GET @Path("sayHello") @Produces("text/plain") @RolesAllows("ADMIN") public String sayHello() { return "Hello World!"; } }