8.4.4. セキュリティ保護されていないコンテキストを読み取り専用にして JNDI へのセキュアなアクセスを確保

JNDI/HTTP ネーミングサービスで利用できる別の機能として、未認証のユーザには読み取り専用モードでアクセスできるコンテキストを定義する機能です。認証層を使うサービスには、これは重要となる可能性があります。例えば、 SRPLoginModule は認証に利用する SRP サーバーインターフェースを検索する必要があります。本項ではここから、JBoss Enterprise Application Platform においてどのように読み取り専用がどのように動作するかを説明していきます。
まず、invoker.sar/WEB-INF/web.xmlReadOnlyJNDIFactory を宣言すると、/invoker/ReadOnlyJNDIFactoryにマッピングします。
<servlet>
    <servlet-name>ReadOnlyJNDIFactory</servlet-name>
    <description>A servlet that exposes the JBoss JNDI Naming service stub
          through http, but only for a single read-only context. The return content 
          is serialized MarshalledValue containing the org.jnp.interfaces.Naming 
          stub.
    </description>
    <servlet-class>org.jboss.invocation.http.servlet.NamingFactoryServlet</servlet-class>
    <init-param>
        <param-name>namingProxyMBean</param-name>
        <param-value>jboss:service=invoker,type=http,target=Naming,readonly=true</param-value>
    </init-param>
    <init-param>
        <param-name>proxyAttribute</param-name>
        <param-value>Proxy</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<!-- ... -->
                        
<servlet-mapping>
    <servlet-name>ReadOnlyJNDIFactory</servlet-name>
    <url-pattern>/ReadOnlyJNDIFactory/*</url-pattern>
</servlet-mapping>
このファクトリは、invoker へ接続する必要がある JNDI スタブのみを提供します。ここでは、invoker は jboss:service=invoker,type=http,target=Naming,readonly=true となっており、http-invoker.sar/META-INF/jboss-service.xml ファイルにて宣言されます。
   <mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
      name="jboss:service=invoker,type=http,target=Naming,readonly=true">
      <attribute name="InvokerName">jboss:service=Naming</attribute>
      <attribute name="InvokerURLPrefix">http://</attribute>
      <attribute name="InvokerURLSuffix">:8080/invoker/readonly/JMXInvokerServlet</attribute>
      <attribute name="UseHostName">true</attribute>
      <attribute name="ExportedInterface">org.jnp.interfaces.Naming</attribute>
      <attribute name="JndiName"></attribute>
      <attribute name="ClientInterceptors">
          <interceptors>
             <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
             <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
             <interceptor>org.jboss.naming.interceptors.ExceptionInterceptor</interceptor>
             <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
          </interceptors>
      </attribute>
   </mbean>
クライアント側のプロキシは、サーバー側にある特定の invoker サーブレットに応答する必要があります。ここでの設定は/invoker/readonly/JMXInvokerServletへの実際の呼出しが含まれています。実際には、これは読み取り専用フィルタが付けられた標準の JMXInvokerServlet となっています。
    <filter>
        <filter-name>ReadOnlyAccessFilter</filter-name>
        <filter-class>org.jboss.invocation.http.servlet.ReadOnlyAccessFilter</filter-class>
        <init-param>
            <param-name>readOnlyContext</param-name>
            <param-value>readonly</param-value>
            <description>The top level JNDI context the filter will enforce
                read-only access on. If specified only Context.lookup operations
                will be allowed on this context. Another other operations or
                lookups on any other context will fail. Do not associate this
                filter with the JMXInvokerServlets if you want unrestricted
                access. </description>
        </init-param>
        <init-param>
            <param-name>invokerName</param-name>
            <param-value>jboss:service=Naming</param-value>
            <description>The JMX ObjectName of the naming service mbean </description>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>ReadOnlyAccessFilter</filter-name>
        <url-pattern>/readonly/*</url-pattern>
    </filter-mapping>

    <!-- ... -->
    <!-- A mapping for the JMXInvokerServlet that only allows invocations 
            of lookups under a read-only context. This is enforced by the
            ReadOnlyAccessFilter 
            -->
    <servlet-mapping>
        <servlet-name>JMXInvokerServlet</servlet-name>
        <url-pattern>/readonly/JMXInvokerServlet/*</url-pattern>
    </servlet-mapping>
readOnlyContext パラメーターがreadonlyに設定されていると、ReadOnlyJNDIFactoryからJBoss にアクセスする場合、readonly コンテキストのデータにのみアクセスができるようになっています。使用方法を示すコードを以下に示します。
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, 
                "org.jboss.naming.HttpNamingContextFactory");
env.setProperty(Context.PROVIDER_URL, 
                "http://localhost:8080/invoker/ReadOnlyJNDIFactory");

Context ctx2 = new InitialContext(env);
Object data = ctx2.lookup("readonly/data");
読み取り専用コンテキスト以外のオブジェクトをルックアップしようとすると失敗します。JBoss にはreadonly コンテキストのデータは含まれていませんので、ご自身で作成しない限りreadonly コンテキストの使い道はありません。