Web コンテナー内での JAX-RS アプリケーションの保護

使用可能なセキュリティー・サービスを Web コンテナーから使用して、REST (Representational State Transfer) リソースを保護することができます。ユーザー認証、トランスポート・セキュリティー、許可制御、およびユーザーからロールへのマッピング を定義する、各種のセキュリティー・メカニズムを構成することができます。

始める前に

適切にセキュリティー制約を定義するには、 ユーザーのアプリケーションおよびそのアプリケーションが公開する RESTful リソースについての 知識があることが重要です。この知識は、アプリケーション およびアプリケーションが公開する個々のリソースが必要とする、適切なセキュリティー・ロール を決定するのに役立ちます。

REST アプリケーションをどのように保護するのかを 示すため、このトピックでは AddressBookApp という名前の REST アプリケーション例を使用します。

アプリケーション・サーバー へのアプリケーションのインストールを完了しておく 必要があります。例えば、AddressBookApp アプリケーション をインストールした後、profile_root/config/cells/cellName/applications/applicationName.ear/deployments/applicationName_war/applicationName.war/WEB-INF ディレクトリー 内の AddressBookApp デプロイメント記述子は、次の例のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_1255468655347">
 <display-name>Sample REST Web Application</display-name>
  <servlet>
    <servlet-name>AddressBookApp</servlet-name>
    <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.test.AddressBookApplication</param-value>
</init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>AddressBookApp</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app>
この例では、サーブレット・マッピング は、REST リソースが /app_root_context/rest ディレクトリーの下で 処理されることを示しています。ここで、app_root_context は、アプリケーションの インストール中に構成したものです。デフォルトのルート・コンテキストは / です。

WebSphere Application Server に対してセキュリティーを使用可能にする必要があります。

このタスクについて

アプリケーション・サーバー環境で稼働する REST アプリケーションに認証および許可制約を適用するのに、Web コンテナーを使用できます。認証は、最小レベルのセキュリティーを必要とし、 それ以上のリソース保護は呼び出し側の ID によっては必要な場合もあるというような 業務 REST リソースにとっては、基本的なセキュリティー要件 です。

REST リソースに対して、以下のセキュリティー・メカニズムを 構成できます。
  • ユーザーが HTTP 基本認証またはフォーム・ログインのいずれかを使用して、アプリケーション への認証を行うことを必要とする。
  • REST リソースを起動するときにはトランスポートに SSL チャネルを使用するように、 アプリケーションを構成する。
  • REST リソース・パターンにロール・ベースの許可制約を定義する。
  • ユーザー ID およびロールを判定するために、アノテーション付き SecurityContext オブジェクトの プログラマチックな使用を実装する。

手順

  1. アプリケーション・サーバーに対してセキュリティーが有効になっていることを確認します。
    1. WebSphere Application Server 管理コンソールを開始します。

      デプロイメント・マネージャーを開始し、ブラウザーに WebSphere Application Server Network Deployment サーバーのアドレスを入力します。デフォルトでは、コンソールは http://your_host.your_domain:9060/ibm/console にあります。

      現在セキュリティーが使用不可になっている場合は、 ユーザー ID を要求するプロンプトが出されます。任意のユーザー ID を使用してログインします。 ただし、セキュリティーが現在有効になっている場合は、 ユーザー ID とパスワードの両方を要求するプロンプトが出されます。 定義済みの管理ユーザー ID とパスワードを使用してログインします。

    2. セキュリティー」>「グローバル・セキュリティー」とクリックします。

      アプリケーション・セキュリティーを使用可能にする」を選択します。

      トラブルの回避 (Avoid trouble) トラブルの回避 (Avoid trouble): 管理セキュリティーを 使用可能にする必要があります。アプリケーション・セキュリティーを使用可能にできるのは、 管理セキュリティーが使用可能になっている場合のみです。gotcha
  2. セキュリティー制約を追加します。
    セキュリティー制約をアプリケーションに追加するには、アプリケーションの web.xml ファイルを 編集するか、アセンブリー・ツールを使用 します。以下のコード・スニペットは、 AddressBookApp サンプル・アプリケーションに適用されるセキュリティー制約です。
    <!-- Security constraint for the sample application -->
      <security-constraint id="SecurityConstraint_1">
        <!-- This defines the REST resource associated with the constraint. -->
        <web-resource-collection id="WebResourceCollection_1">
          <web-resource-name>AddressBookApp</web-resource-name>
          <description>Protection area for Rest resource /addresses </description>
          <url-pattern>/rest/addresses</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
        </web-resource-collection>
    
        <!—This defines an authorization constraint by requiring Role1 for the resource. -->
        <auth-constraint id="AuthConstraint_1">
          <description>Used to guard resources under this url-pattern </description>
          <role-name>Role1</role-name>
        </auth-constraint>
      </security-constraint>

    この例では、HTTP GET または POST 要求に応答できる、/root_context/rest/addresses に置かれた Web リソースがあります。その Web リソースにセキュリティー制約 AuthConstraint_1 が適用されます。この許可制約は、ユーザーがリソースにアクセスするには、 ロール Role1 が必要であることを指定 しています。

  3. 以下のセキュリティー・メカニズムのうち 1 つ以上を選択して、 REST アプリケーションに対する構成を行います。
    • 基本 HHTP 認証を使用可能にする。
      1. 前に説明されているように、web.xml ファイルを編集することによって、セキュリティー制約を 追加します。
      2. 基本 HTTP 認証を使用可能にするように web.xml ファイルを構成します。
        基本 HTTP 認証の使用を指定するには、 アプリケーションの web.xml ファイルを編集して、以下のエレメントを 追加します。デフォルトでは、 アプリケーション・サーバー・セキュリティー・ランタイム環境はこの認証方式を使用します。
        <!-- This defines a HTTP basic authentication login configuration. -->
         <login-config>
                <auth-method>BASIC</auth-method>
                <realm-name>test realm</realm-name>
         </login-config>
        これで、HTTP 基本認証方式 が定義されます。このリソースにアクセスしようとするユーザー は、ログイン時にクレデンシャルを必要とします。
    • フォーム・ログインを使用可能にする。
      1. 前に説明されているように、web.xml ファイルを編集することによって、セキュリティー制約を 追加します。
      2. フォーム・ログインの使用を指定するには、アプリケーションの web.xml ファイルを編集して、 以下のエレメントを追加します。
        <login-config>
              <auth-method>FORM</auth-method>
              <form-login-config>
                 <form-login-page>/logon.jsp</form-login-page>
                 <form-error-page>/logonError.jsp</form-error-page>
              </form-login-config>
        </login-config>
        logon.jsp および logonError.jsp Web ページ値を、それぞれ独自のフォーム・ログインおよびエラー処理で置き換えることが重要です。アプリケーションにアクセスするとき、ユーザーは logon.jsp Web ページを介して認証のために転送されます。認証障害がある場合、ユーザーは logonError.jsp Web ページに転送されます。次の例では、アプリケーション Web アーカイブ (WAR) ファイル内での logon.jsp ページと logonError.jsp ページの配置を示します。
        META-INF
              logon.jsp
              logonError.jsp
              WEB-INF/classes/
              WEB-INF/classes/
              WEB-INF/classes/com/
              WEB-INF/classes/com/test/   
              WEB- NF/classes/com/test/AddressBookApplication.class
              WEB-INF/classes/com/test/AddressBookResource.class
        以下の コード・スニペットは、ログオン・フォームの例を示します。
        <html>
        <head>
            <title>Login Page</title>
        </head>
        <h2>Hello, please log in:</h2>
         <br><br>
        <form action="j_security_check" method=post>
            <p><strong>Please Enter Your User Name: </strong>
            <input type="text" name="j_username" size="25">
            <p><p><strong>Please Enter Your Password: </strong>
            <input type="password" size="15" name="j_password">
            <p><p>
            <input type="submit" value="Submit">
            <input type="reset" value="Reset">
        </form>
        </html>
    • アプリケーションに対して SSL を使用可能にする。
      1. 前に説明されているように、web.xml ファイルを編集することによって、セキュリティー制約を 追加します。
      2. アプリケーションの web.xml ファイルを編集し、以下のエレメント を security-constraint エレメント内に追加します。
        <user-data-constraint id="UserDataConstraint_1">
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
         </user-data-constraint>
        SSL を使用したくない場合は、この制約をスキップするか、または CONFIDENTIAL 値を NONE で置き換えることができます。
    • 許可制御を使用可能にして、URL パターンを使用してリソースを保護する。
      1. 前に説明されているように、web.xml ファイルを編集することによって、セキュリティー制約を 追加します。
      2. アプリケーションの web.xml ファイルを編集し、以下のエレメント を security-constraint エレメント内に追加します。以下の例では、Role1 および Role2 は、 それぞれ REST リソース /rest/addresses および /rest/resources/{i} を 保護することを指定しています。
        <security-constraint id="SecurityConstraint_1">
            <web-resource-collection id="WebResourceCollection_1">
              <web-resource-name>AddressBookApp</web-resource-name>
              <description>Protection area for Rest Servlet</description>
              <url-pattern>/rest/addresses</url-pattern>
              <http-method>GET</http-method>
              <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint id="AuthConstraint_1">
                 <description> Role1 for this rest resource </description>
                 <role-name>Role1</role-name>
              </auth-constraint>
        </security-constraint>
        
        <security-constraint id="SecurityConstraint_2">
            <web-resource-collection id="WebResourceCollection_2">
              <web-resource-name>AddressBookApp</web-resource-name>
              <description>Protection area for Rest Servlet</description>
              <url-pattern>/rest/addresses/*</url-pattern>
              <http-method>GET</http-method>
              <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint id="AuthConstraint_2">
                 <description> Role2 for this rest resource </description>
                 <role-name>Role2</role-name>
              </auth-constraint>
        </security-constraint>

        この例では、 Role1 のメンバーであるユーザーのみが root-context/rest/addresses に アクセスでき、Role2 のメンバーであるユーザーのみがリソース root-context/rest/addresses/{i} にアクセスできます。

        トラブルの回避 (Avoid trouble) トラブルの回避 (Avoid trouble): 保護リソース のパスの接頭部として、定義したセキュリティー制約内のサーブレット・マッピングを付けることが 重要です。バイパスされるアクセス検査がないようにするため、 サーブレットを /* パスにマップすることを選択できます。このマッピング は、ルート・コンテキストの下のすべてのリソースを保護します。gotcha
        以下の例のように、 <web-app> エレメント内にロール定義エレメントを挿入して、 使用するロールを必ず定義してください。
        <security-role id="SecurityRole_1">
            <description>This is Role1</description>
            <role-name>Role1</role-name>
        </security-role>
        <security-role id="SecurityRole_2">
            <description>This is Role2</description>
            <role-name>Role2</role-name>
        </security-role>

        デプロイメント記述子に加えられた変更は、 アプリケーション・サーバー・ランタイム環境に自動的に適用されます。アプリケーションまたはサーバーを再始動する必要は ありません。他のタイプの変更 (マッピング URL など) は、アプリケーション・サーバーの 再始動を必要とします。変更を確実に有効にするため、 アプリケーションを再始動することをお勧めします。

    • アノテーション付きセキュリティー・コンテキストをプログラムで使用する。
      アプリケーション開発者 は JAX-RS @SecurityContext アノテーションを使用して、 セキュリティー・コンテキストをサーバー・サイドのリソースへとプログラムでカスケードさせることができ、 また、実行時にセキュリティー属性の定義を使用可能にすることができます。 SecurityContext インターフェースによって提供される 機能を以下に示します。
      public String getAuthenticationScheme()
      public Principal getUserPrincipal()
      public boolean isUserInRole(String role)
      以下の例 は、SecurityContext インターフェースを示します。
      package com.test;
      
      import javax.ws.rs.GET;
      import javax.ws.rs.Consumes;
      import javax.ws.rs.POST;
      import javax.ws.rs.Path;
      import javax.ws.rs.PathParam;
      import javax.ws.rs.Produces;
      import javax.ws.rs.ext.*;
      import javax.ws.rs.core.SecurityContext;
      import javax.ws.rs.core.Context;
      
      /**   
       * A sample resource that provides access to an address book. 
       * 
       */
      @Path(value="/addresses")
      public class AddressBookResource {
      	
      		@Context private SecurityContext securityContext;
          
          private static String[] list = new String[] {
              "Michael",
              "Ron",
              "Jane",
              "Sam"
          };
          
          @GET
          @Produces(value="text/plain")
          public String getList() {
             // retrieve the authentication scheme that was used(e.g. BASIC)
             String authnScheme = securityContext.getAuthenticationScheme());
             // retrieve the name of the Principal that invoked the resource
             String username = securityContext.getUserPrincipal().getName());
             // check if the current user is in Role1 
              Boolean isUserInRole = securityContext.isUserInRole(“Role1”);
          	 
              StringBuffer buffer = new StringBuffer();
              buffer.append("{");
              for (int i = 0; i < list.length; ++i) {
                  if (i != 0) 
                      buffer.append(", ");
                  buffer.append(list[i]);
              }
              buffer.append("}");
              
              return buffer.toString();
          }
      }
    • セキュリティー・クライアント・ハンドラーを使用して、基本 HTTP 認証を実行する。
      オプションで、 セキュリティー・クライアント・ハンドラーを使用して、保護された JAX-RS リソースで基本 HTTP 認証を 実行できます。以下の例では、このタスクを実行する単純なプログラミング・モデル を示します。
      /**
       * This snippet illustrates the use of the JAX-RS SecurityHandler by a
       * client to perform HTTP basic authentication with a target service.
       */ 
       
       import org.apache.wink.client.ClientConfig;
       import org.apache.wink.client.Resource;
       import org.apache.wink.client.RestClient;
       import org.apache.wink.client.handlers.BasicAuthSecurityHandler;
      
       ClientConfig config = new ClientConfig();
        BasicAuthSecurityHandler secHandler = new    
       BasicAuthSecurityHandler();
      
       // Set the user credential.
       secHandler.setUsername("user1");
       secHandler.setPassword("security");
      
       // Add this security handler to the handlers chain.
       config.handlers(secHandler);
      
       // Create the REST client instance. 
       RestClient client = new RestClient(config);
      
       // Create the resource instance to interact with 
       // substitute for your resource address
       resource =  
        client.resource("http://localhost:8080/path/to/resource");
      
      // Now you are ready to call your resource.
      BasicAuthSecurityHandler クラスを使用する場合は、 URL に HTTPS スキームを使用してリソースの宛先を指定してください。また、ターゲット・アプリケーション が SSL に対応していることを確認してください。ユーザー・クレデンシャルを送信する際には、 SSL 接続を使用することを強くお勧めします。BasicAuthSecurityHandler クラスで、SSL 要件を明示的にオフにすることができます。オフにする場合は、セキュリティー・ハンドラーで setSSLRequired メソッドに値 false を指定して呼び出します。この値は、デフォルトで true に設定されています。
      secHandler.setSSLRequired(false);
      オプションで、 次のようにして、クライアントに対して Java™ コマンド行でユーザー・クレデンシャルを提供することもできます。
      java -Duser=test_user -Dpassword=your_password  your_client_program
      オプションで、ユーザー・クレデンシャルを プロパティー・ファイルから取得できます。このファイルの場所は Java コマンド行に次のように 指定します。
      java -Dclientpropsdir=directory_for_your_properties_file  your_client_program
      ここで、directory_for_your_properties_file には、user および password プロパティー が設定されている wink.client.props ファイルが含まれています。

タスクの結果

セキュリティー制約を定義した後は、アプリケーション内に定義された REST リソース へのアクセスには、ユーザー認証が成功することのみが条件に なります。さらに、ロール制約をさまざまなリソース URL パターンに適用した場合、 それらのリソースへのアクセスがロールに基づいて行われるようになります。

以下の例では、前述の手順を使用してセキュリティー制約が定義された、 AddressBookApp サンプル・アプリケーションの web.xml デプロイメント記述子 を示します。
<web-app id="WebApp_1255468655347">
    <display-name>Sample REST Web Application</display-name>
    <servlet>
        <servlet-name>AddressBookApp</servlet-name>
        <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.test.AddressBookApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AddressBookApp</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <security-constraint id="SecurityConstraint_1">
      <web-resource-collection id="WebResourceCollection_1">
        <web-resource-name>AddressBookApp</web-resource-name>
        <description>Protection area for Rest Servlet</description>
        <url-pattern>/rest/addresses</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint id="AuthConstraint_1">
         <description>Role1 for this rest servlet</description>
         <role-name>Role1</role-name>
      </auth-constraint>
      <user-data-constraint id="UserDataConstraint_1">
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>
    <security-constraint id="SecurityConstraint_2">
      <web-resource-collection id="WebResourceCollection_2">
        <web-resource-name>AddressBookApp</web-resource-name>
        <description>Protection area for Rest Servlet</description>
        <url-pattern>/rest/addresses/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint id="AuthConstraint_2">
         <description>Role2 for this rest servlet</description>
         <role-name>Role2</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 is Role1</description>
         <role-name>Role1</role-name>
    </security-role>
    <security-role id="SecurityRole_2">
         <description>This is Role2</description>
         <role-name>Role2</role-name>
    </security-role>
    <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
         <form-login-page>/logon.jsp</form-login-page>
         <form-error-page>/logonError.jsp</form-error-page>
      </form-login-config>
    </login-config>
</web-app>

次のタスク

管理コンソールを使用して、JAX-RS アプリケーションのセキュリティー を管理します。


トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_impl_securejaxrs_webcont
ファイル名:twbs_jaxrs_impl_securejaxrs_webcont.html