プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Web Services Manager拡張可能アプリケーションの開発
12c (12.2.1.2)
E82847-01
目次へ移動
目次

前
次

3 サンプル・カスタム・アサーションの管理

この章では、サンプル・カスタム・アサーションについて説明し、各カスタム・アサーションのサンプル・コードを示します。また、サンプルに実装されている主な機能についても説明します。

次の各トピックで、さらに詳しく説明します。

3.1 カスタム・アサーションでのIPアドレスの検証

IPアドレス検証のカスタム・アサーションのサンプルでは、Webサービスに対して実行されたリクエストが、有効なIPアドレスのセットから実行されたかどうかを検証します。カスタム・ポリシー・アサーションでは、有効なIPアドレスをカンマ区切りの値のリストとして含めることができます。その他のIPアドレスからのリクエストは、FAILED_CHECKレスポンスになります。

この項には次のトピックが含まれます:

3.1.1 カスタム・アサーション・エグゼキュータを使用したIPアドレスの検証

カスタム・アサーション・エグゼキュータを使用してIPアドレスを検証するには、次のサンプルを参照してください。

このサンプル・カスタム・アサーション・エグゼキュータを次に示します。

package sampleassertion;
 
import oracle.wsm.common.sdk.IContext;
import oracle.wsm.common.sdk.IMessageContext;
import oracle.wsm.common.sdk.IResult;
import oracle.wsm.common.sdk.Result;
import oracle.wsm.common.sdk.WSMException;
import oracle.wsm.policy.model.IAssertionBindings;
import oracle.wsm.policy.model.IConfig;
import oracle.wsm.policy.model.IPropertySet;
import oracle.wsm.policy.model.ISimpleOracleAssertion;
import oracle.wsm.policy.model.impl.SimpleAssertion;
import oracle.wsm.policyengine.impl.AssertionExecutor;
 
public class IpAssertionExecutor extends AssertionExecutor {
 
    public IpAssertionExecutor() {
    }
 
    public void destroy() {
    }
 
    public void init(oracle.wsm.policy.model.IAssertion assertion,
                     oracle.wsm.policyengine.IExecutionContext econtext,
                     oracle.wsm.common.sdk.IContext context) {
        this.assertion = assertion;
        this.econtext = econtext;
    }
 
    public oracle.wsm.policyengine.IExecutionContext getExecutionContext() {
        return this.econtext;
    }
 
    public boolean isAssertionEnabled() {
        return ((ISimpleOracleAssertion)this.assertion).isEnforced();
    }
 
    public String getAssertionName() {
        return this.assertion.getQName().toString();
    }
 
    /**
     * @param context
     * @return
     */
    public IResult execute(IContext context) throws WSMException {
        try {
         oracle.wsm.common.sdk.IMessageContext.STAGE stage =
 ((oracle.wsm.common.sdk.IMessageContext)context).getStage();
 
            if (stage  == IMessageContext.STAGE.request)  {    
 

               IAssertionBindings bindings =
 ((SimpleAssertion)(this.assertion)).getBindings();
               IConfig config = bindings.getConfigs().get(0);
               IPropertySet propertyset = config.getPropertySets().get(0);
               String valid_ips = propertyset.getPropertyByName("valid_
ips").getValue();
               String ipAddr = ((IMessageContext)context).getRemoteAddr();
               IResult result = new Result();
 
               if (valid_ips != null && valid_ips.trim().length() > 0) {
                    String[] valid_ips_array = valid_ips.split(",");
                    boolean isPresent = false;
                    for (String valid_ip : valid_ips_array) {
                      if (ipAddr.equals(valid_ip.trim())) {
                          isPresent = true;
                      }
                    }
                    if (isPresent) {
                       result.setStatus(IResult.SUCCEEDED);
                    } else {
                       result.setStatus(IResult.FAILED);
                       result.setFault(new WSMException(WSMException.FAULT_FAILED
_CHECK));
                    }
               } else {
                result.setStatus(IResult.SUCCEEDED);
               }
               return result;
          }
        } catch (Exception e) {
            throw new WSMException(WSMException.FAULT_FAILED_CHECK, e);
        }
    }
 
    public oracle.wsm.common.sdk.IResult
 postExecute(oracle.wsm.common.sdk.IContext p1) {
        IResult result = new Result();
        result.setStatus(IResult.SUCCEEDED);
        return result;
    }
}

3.1.2 ポリシー・ファイルを使用したIPアドレスの検証

ポリシー・ファイルを使用してIPアドレスを検証するには、次のサンプルを参照してください。

このサンプル・ポリシー・ファイルを次に示します。

<?xml version = '1.0' encoding = 'UTF-8'?>
<wsp:Policy xmlns="http://schemas.xmlsoap.org/ws/2004/09/policy"
 xmlns:orasp="http://schemas.oracle.com/ws/2006/01/securitypolicy"
orawsp:status="enabled"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-uti
lity-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orawsp:category="security"
 orawsp:attachTo="binding.server" wsu:Id="ip_assertion_policy"
xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
 xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
wsp:Name="oracle/ip_assertion_policy">
           <orasp:ipAssertion orawsp:Silent="true" orawsp:Enforced="true"
 orawsp:name="WSSecurity IpAsertion validator"
 orawsp:category="security/authentication">
               <orawsp:bindings>
                    <orawsp:Config orawsp:name="ipassertion"
 orawsp:configType="declarative">
                         <orawsp:PropertySet orawsp:name="valid_ips">
                               <orawsp:Property orawsp:name="valid_ips"
 orawsp:type="string" orawsp:contentType="constant">
                                    <orawsp:Value>140.87.6.143,10.178.93.107</orawsp:Value>
                                </orawsp:Property>
                         </orawsp:PropertySet>
                     </orawsp:Config>
               </orawsp:bindings>
            </orasp:ipAssertion>
</wsp:Policy>

3.1.3 policy-config.xmlファイルを使用したIPアドレスの検証

policy-config.xmlファイルを使用してカスタム・アサーション・エグゼキュータを指定するには、次のサンプルを参照してください。

「カスタム・アサーション・エグゼキュータの指定」で説明したように、カスタム・ポリシーを使用してカスタム・ポリシー・エグゼキュータを指定することもできます。

<?xml version="1.0" encoding="UTF-8"?>
<policy-config>
    <policy-model-config>
      <entry>
        <key namespace="http://schemas.oracle.com/ws/2006/01/securitypolicy"
 element-name="ipAssertion"/>
        <executor-classname>sampleassertion.IpAssertionExecutor</executor-classname>
      </entry>
    </policy-model-config>
</policy-config>

3.1.4 Webサービスを使用したIPアドレスの検証

Webサービスを使用してIPアドレスを検証するには、次のサンプルを参照してください。

「Webサービスへのカスタム・ポリシーのアタッチ」で説明したように、Webサービスにカスタム・アサーションをアタッチできます。

package project1; 
import javax.jws.WebService;
import weblogic.wsee.jws.jaxws.owsm.SecurityPolicies;
@WebService
@SecurityPolicy(uri="policy:oracle/ip_assertion_policy")
public class Class1 {
    public Class1() {
        super();
    }
 
    public String echo1() {
        return "one";
    }
}

3.1.5 JSEクライアントを使用したIPアドレスの検証

Webサービスから生成されたJSEクライアントを使用してIPアドレスを検証するには、次のサンプルを参照してください。

次のサンプルは、「Webサービスを使用したIPアドレスの検証」で示したWebサービスから生成されるJSEクライアントを示しています。

package project1;
import javax.xml.ws.WebServiceRef;
 
public class Class1PortClient
{
  @WebServiceRef
  private static Class1Service class1Service;
  public static void main(String [] args)
  {
    class1Service = new Class1Service();
    Class1 port = class1Service.getClass1Port();
    // Add your code to call the desired methods.
 
    System.out.println(port.echo1());
  }
}

3.2 カスタム・アサーションでのIPアドレス検証の実行

カスタム・アサーションでIPアドレスの検証を実行するには、カスタム・アサーションとJARファイルを作成し、カスタム・ポリシーをカスタム・ストアに追加し、CLASSPATHを更新し、カスタム・ポリシーをWebサービスにアタッチして、最後にWebサービスをテストします。

カスタム・アサーションでIPアドレスの検証を実行するには:

  1. 「カスタム・アサーション・エグゼキュータを使用したIPアドレスの検証」で説明したサンプル・コードを使用して、カスタム・アサーションとカスタム・アサーション・エグゼキュータを作成します。これらのサンプルは次の主な機能を示しています。
    • カスタム・アサーションにIPアドレスの有効な値を指定します。

      <orawsp:PropertySet orawsp:name="valid_ips">
        <orawsp:Property orawsp:name="valid_ips" orawsp:type="string"
       orawsp:contentType="constant">
        <orawsp:Value>140.87.6.143,10.178.93.107</orawsp:Value>
        </orawsp:Property>
      </orawsp:PropertySet>
      

      詳細は、「カスタム・アサーションのパラメータの指定」を参照してください。

    • カスタム・アサーション・エグゼキュータの実行ステージを表示します。

      oracle.wsm.common.sdk.IMessageContext.STAGE stage =
       ((oracle.wsm.common.sdk.IMessageContext)context).getStage()
      

      詳細は、「OWSMカスタム・セキュリティ・アサーションへのアクセス」を参照してください。

    • カスタム・アサーション・エグゼキュータからIPアドレスにアクセスします。

      IConfig config = bindings.getConfigs().get(0);
      IPropertySet propertyset = config.getPropertySets().get(0);
      String valid_ips = propertyset.getPropertyByName("valid_ips").getValue();
      

      詳細は、「カスタム・アサーションのパラメータの指定」を参照してください。

    • コンテキスト・プロパティ・リモート・アドレスにアクセスします。

      String ipAddr = ((IMessageContext)context).getRemoteAddr();
      

      詳細は、「OWSMコンテキスト・プロパティの検査」を参照してください。

    • 失敗した場合、リクエストの実行が失敗した原因となるフォルトを設定します。

      result.setFault(new WSMException(WSMException.FAULT_FAILED_CHECK));
      

      詳細は、「カスタム・アサーションでの例外処理」を参照してください。

  2. 「カスタム・アサーションJARファイルの作成」の説明に従って、JARファイルを作成します。
  3. 「ポリシー・ストアへのカスタム・ポリシーの追加」の説明に従って、ポリシー・ストアにカスタム・ポリシーを追加します。
  4. 「カスタム・アサーションのデプロイ」の説明に従って、CLASSPATHを更新します。
  5. 「Webサービスへのカスタム・ポリシーのアタッチ」で説明した方法のいずれかを使用して、Webサービスにカスタム・ポリシーをアタッチします。
  6. 「JSEクライアントを使用したIPアドレスの検証」で示したようにJSEクライアントを作成して、Webサービスをテストします。

3.3 カスタム・アサーションでのデータの暗号化と復号化

暗号化と復号化のカスタム・アサーション・サンプルは、インバウンド・メッセージのデータを暗号化するカスタム・アサーションのセットを使用して、そのデータがコンソール、監査証跡、またはログから読み取られないようにします。暗号化されたデータは、データのアクセスを必要とするダウンストリーム・サービスのアウトバウンド・メッセージのために復号化されます。

この項には次のトピックが含まれます:

3.3.1 カスタム・アサーション・エグゼキュータを使用したデータの暗号化と復号化

データの暗号化と復号化を行うサンプル・カスタム・アサーション・エグゼキュータを参照してください。

このサンプル・カスタム・アサーション・エグゼキュータを次に示します。実装の詳細は、「カスタム・アサーションでのデータの暗号化と復号化の実行」を参照してください。

package owsm.custom.soa;
 
import java.util.HashMap;
import java.util.Iterator;
 
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
 
import oracle.wsm.common.sdk.IContext;
import oracle.wsm.policy.model.IAssertion;
import oracle.wsm.policyengine.IExecutionContext;
import oracle.wsm.policyengine.impl.AssertionExecutor;
 
import org.w3c.dom.Element;
import org.w3c.dom.Node;
 
/**
 * A base class for OWSM custom assertions that specific classes can extend. It
 * contains common code and variables used accross all custom assertions.
 * 
 * All custom assertions must extend the AssertionExecutor class.
 */
public abstract class CustomAssertion
  extends AssertionExecutor
{
 
 
  protected final static String PROP_DEBUG = "debugFlag";
  
  protected final static String DEBUG_START =
 "===========================================================>>>";
  protected final static String DEBUG_END =
 "<<<===========================================================";
 
  protected IAssertion mAssertion = null;
  protected IExecutionContext mEcontext = null;
  protected oracle.wsm.common.sdk.IContext mIcontext = null;
  
  /**
   * A tag or text to display when printing debug information to identify the
   * content.
   */
  protected String mTag;
 
  /**
   * Constructor
   */
  public CustomAssertion(String tag)
  {
    super();
    mTag = tag;
  } // CustomAssertion()
 
  /**
   * Implemented from parent class
   */
  public void init(IAssertion iAssertion,
                      IExecutionContext iExecutionContext,
                      IContext iContext)
  {
    mAssertion = iAssertion;
    mEcontext = iExecutionContext;
    mIcontext = iContext;
    //IAssertionBindings bindings = ((SimpleAssertion)

 (mAssertion)).getBindings();
  } // init()
  /**
   * Implemented from parent class
   */
  public void destroy()
  {
    // Nothing to do.
  } // destroy()
  
  /**
   * A utility method for extracting the node specified by <code>xpathStr</code>
   * (with namespaces defined by <code>namespaces</code>) from  
 *<code>payload</code>
   * 
   * This method will print an stack trace if their is an exception. If you want
 *to
   * return the exception instead then modify the method appropriately.
   * 
   * @param payload the payload
   * @param namespaces the namespaces referenced by <code>xpathStr</code>
   * @param xpathStr an XPath query defining how to extract a node from
 *<code>payload</code>
   * @return
   */
  public static Node getDataNode(Element payload, final HashMap<String, String>

 namespaces, String xpathStr)
  {
    Node node = null;
    
    try
    {
      // Create a namespace context based on the namespaces passed in.
      //
      NamespaceContext ctx = new NamespaceContext()
      {
        public String getNamespaceURI(String prefix)
        {
          return namespaces.get(prefix);
        }
        // Dummy implementation - not used
        public Iterator getPrefixes(String val)
        {
          return null;
        }
        // Dummy implemenation - not used
        public String getPrefix(String uri)
        {
          return null;
        }
      };
      XPathFactory xpathFact = XPathFactory.newInstance();
      XPath xpath = xpathFact.newXPath();
      xpath.setNamespaceContext(ctx);
            node = (Node)xpath.evaluate(xpathStr, payload, XPathConstants.NODE);
    }
    catch (XPathExpressionException ex)
    {
      ex.printStackTrace();
      return null;
    }
    
    return node;
  } // getDataNode()
  
} 

3.3.2 カスタム・アサーション・エグゼキュータを使用したインバウンド・メッセージの要素の暗号化

インバウンド・メッセージの要素を暗号化するサンプル・カスタム・アサーション・エグゼキュータを参照してください。

このサンプル・カスタム・アサーション・エグゼキュータを次に示します。

package owsm.custom.soa;
 
import java.util.HashMap;
 
import javax.xml.soap.SOAPBody;
 
import oracle.wsm.common.sdk.IContext;
import oracle.wsm.common.sdk.IMessageContext;
import oracle.wsm.common.sdk.IResult;
import oracle.wsm.common.sdk.Result;
import oracle.wsm.common.sdk.SOAPBindingMessageContext;
import oracle.wsm.common.sdk.WSMException;
import oracle.wsm.policy.model.IAssertionBindings;
import oracle.wsm.policy.model.IConfig;
import oracle.wsm.policy.model.IProperty;
import oracle.wsm.policy.model.IPropertySet;
import oracle.wsm.policy.model.impl.SimpleAssertion;
 
import oracle.xml.parser.v2.XMLElement;
 
import org.w3c.dom.Node;
 
 
/**
 * A custom assertion class for encrypting an element of an inbound message.
 */
public class InboundEncryptor
  extends CustomAssertion
{
  /**
   * Constructor
   */
  public InboundEncryptor()
  {
    super("[InboundEncryptor] ");
  } // InboundEncryptor()
 

 
  /**
   * Process an inbound message for the given invocation context
   *
   * @param iContext the invocation context for a specific message
   * @return the result of any actions taken. It can return a success message or
   *         a fault with an exception message
   */
  public IResult execute(IContext iContext)
  {
    // Create the result that's going be populate with success or failure
    // depending on what happens.
    //
    IResult result = new Result();
    
    // Specify whether we are in debug mode or not. If true then debug statements
    // will be printed to the log file.
    // This can be set to true in the OWSM policy assertion.
    //
    boolean debug = false;
 
    try
    {
      // Get the property set which contains properties defined in the OWSM
      // policy assertion.
      //
      IAssertionBindings bindings = ((SimpleAssertion)
 (mAssertion)).getBindings();
      IConfig config = bindings.getConfigs().get(0);
      IPropertySet propertyset = config.getPropertySets().get(0);
 
      // Now that we have the property set, let's check it for the specific
      // properties we care about.
      //
      
      // Check for the debug flag property.
      //
      IProperty debugProp = propertyset.getPropertyByName(PROP_DEBUG);
      if (debugProp != null)
      {
        String debugStr = debugProp.getValue();
        debug = Boolean.valueOf(debugStr).booleanValue();
      }
      if (debug)
      {
        System.out.println(mTag+DEBUG_START);
        System.out.println(mTag+this.getClass().getSimpleName()+".execute()
 Starting...");
        System.out.println(mTag+"In debug mode");
      }
      
      // Check for the stage. We only care about the request stage for this
      // implementation.
      //
      IMessageContext.STAGE stage = ((IMessageContext) iContext).getStage();
      if (debug) System.out.println(mTag+"stage="+stage);
      if (stage != IMessageContext.STAGE.request)
      {
        result.setStatus(IResult.SUCCEEDED);
        if (debug)
        {
          System.out.println(mTag+"Nothing to process in this stage. Returning");
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
      // Get the encryption key, which is a property on the assertion.
      //
      String key = propertyset.getPropertyByName("encryption_key").getValue();
      if (debug) System.out.println(mTag+"key=[" + key + "]");
      if (key == null || key.trim().length() == 0)
      {
        result.setStatus(IResult.FAILED);
        result.setFault(new WSMException("Invalid key"));
        if (debug)
        {
          System.out.println(mTag+"Invalid key");
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
      // As as point of interest, you can get the service URL. This could be used
      // by this class to know which service this message is bound for, and
 //therefore
      // which XPath expression to use.
      // In this example no such logic is needed as we only have one servcie
      // to worry about.
      //
      if (debug)
      {
        String serviceURL = ((IMessageContext) iContext).getServiceURL();
        System.out.println(mTag+"serviceURL=[" + serviceURL+"]");
      }
      // Get the message.
      //
      SOAPBindingMessageContext soapbindingmessagecontext =
 (SOAPBindingMessageContext) iContext;
      javax.xml.soap.SOAPMessage soapMessage =
 soapbindingmessagecontext.getRequestMessage();
      SOAPBody soapElem = soapMessage.getSOAPBody();
      if (debug)
      {
        System.out.println(mTag+"----- Start ORIGINAL inbound message -----");
        ((XMLElement) soapElem).print(System.out);
        System.out.println(mTag+"-----  End ORIGINAL inbound message  -----");
      }
      // Create the XPath to reference the element which is to be encrypted.
      //
      String xpathStr =
 "/soap:Envelope/soap:Body/ns1:process/ns1:order/ns1:ccNum";
      // Build up a namespace list for any namespaces referenced by the
      // XPath expression. This will be the basis for a namespace context
      // created later.
      //
      final HashMap<String, String> namespaces = new HashMap<String, String>();
      namespaces.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
      namespaces.put("ns1", "http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionComposite/ProcessCustomer");
     
      // Extract the node that should be encrypted.
      //
      Node inputNode = getDataNode(soapElem, namespaces, xpathStr);
      if (inputNode == null)
      {
        // Something went wrong, but getDataNode() would've printed out a
 //stacktrace
        // so print out a debug statement and exit.
        //
        result.setStatus(IResult.FAILED);
        result.setFault(new WSMException("Cannot find node with XPath expression:
 "+xpathStr));
        if (debug)
        {
          System.out.println(mTag+"Cannot find node with XPath expression:
 "+xpathStr);
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
  
      // Extract the string value of the element to be encrypted.
      //
      String inputValue = inputNode.getTextContent();
  
      // Get an instance of EncDec and perform the actual encryption.
      //
      EncDec ed = EncDec.getInstance();
      String encryptedInput = ed.encryptStrToStr(inputValue, key);
      if (debug) System.out.println(mTag+"result of encryption=[" + encryptedInput
 + "]");
      // Replace the value of the node with the encrypted value.
      //
      try
      {
        inputNode.setTextContent(encryptedInput);
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
      if (debug)
      {
        System.out.println(mTag+"----- Start MODIFIED inbound message -----");
        ((XMLElement) soapElem).print(System.out);
        System.out.println(mTag+"-----  End MODIFIED inbound message  -----");
      }
      // Set a happy result.
      //
      result.setStatus(IResult.SUCCEEDED);
    }
    catch (Exception e)
    {
      // This is a general or catchall handler.
      //
      result.setStatus(IResult.FAILED);
      result.setFault(new WSMException(WSMException.FAULTCODE_QNAME_FAILED_CHECK,
 e));
      if (debug) System.out.println(this.getClass().getName()+": ERROR: Got an
 exception somewhere...");
    }
    
    if (debug) System.out.println(mTag+DEBUG_END);
    return result;
    
  } // execute()
  
} // InboundEncryptor

3.3.3 カスタム・アサーション・エグゼキュータを使用したアウトバウンド・メッセージの要素の復号化

アウトバウンド・メッセージの要素を復号化するサンプル・カスタム・アサーション・エグゼキュータを参照してください。

このサンプル・カスタム・アサーション・エグゼキュータを次に示します。

package owsm.custom.soa;
 
import java.util.HashMap;
 
import javax.xml.soap.SOAPBody;
 
import oracle.wsm.common.sdk.IContext;
import oracle.wsm.common.sdk.IMessageContext;
import oracle.wsm.common.sdk.IResult;
import oracle.wsm.common.sdk.Result;
import oracle.wsm.common.sdk.SOAPBindingMessageContext;
import oracle.wsm.common.sdk.WSMException;
import oracle.wsm.policy.model.IAssertionBindings;
import oracle.wsm.policy.model.IConfig;
import oracle.wsm.policy.model.IProperty;
import oracle.wsm.policy.model.IPropertySet;
import oracle.wsm.policy.model.impl.SimpleAssertion;
 
import oracle.xml.parser.v2.XMLElement;
 
import org.w3c.dom.Node;
 
 
/**
 * A custom assertion class for decrypting an element of an outbound message.
 */
public class OutboundDecryptor
  extends CustomAssertion
{
 
  /**
   * Constructor
   */
  public OutboundDecryptor()
  {
    super("[OutboundDecryptor] ");
  } // OutboundDecryptor()
 
  //////////////////////////////////////////////////////////////////////////////
 
  /**
   * Process an outbound message for the given invocation context
   *
   * @param iContext the invocation context for a specific message
   * @return the result of any actions taken. It can return a success message or
   *         a fault with an exception message
   */
  public IResult execute(IContext iContext)
  {
    // Create the result that's going be populate with success or failure
    // depending on what happens.
    //
    IResult result = new Result();
 
    // Specify whether we are in debug mode or not. If true then debug statements
    // will be printed to the log file.
    // This can be set to true in the OWSM policy assertion.
    //
    boolean debug = false;
 
    try
    {
      // Get the property set which contains properties defined in the OWSM
      // policy assertion.
      //
      IAssertionBindings bindings = ((SimpleAssertion)
 (mAssertion)).getBindings();
      IConfig config = bindings.getConfigs().get(0);
      IPropertySet propertyset = config.getPropertySets().get(0);
      
      // Now that we have the property set, let's check it for the specific
      // properties we care about.
      //
      
      // Check for the debug flag property.
      //
      IProperty debugProp = propertyset.getPropertyByName(PROP_DEBUG);
      if (debugProp != null)
      {
        String debugStr = debugProp.getValue();
        debug = Boolean.valueOf(debugStr).booleanValue();
      }
      if (debug)
      {
        System.out.println(mTag+DEBUG_START);
        System.out.println(mTag+this.getClass().getSimpleName()+".execute()
 Starting...");
        System.out.println(mTag+"In debug mode");
      }
 
      // Check for the stage. We only care about the request stage for this
      // implementation.
      //
      IMessageContext.STAGE stage = ((IMessageContext) iContext).getStage();
      if (debug) System.out.println(mTag+"stage="+stage);
      if (stage != IMessageContext.STAGE.request)
      {
        result.setStatus(IResult.SUCCEEDED);
        if (debug)
        {
          System.out.println(mTag+"Nothing to process in this stage. Returning");
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
      // Get the encryption key, which is a property on the assertion.
      //
      String key = propertyset.getPropertyByName("decryption_key").getValue();
      if (debug) System.out.println(mTag+"key=[" + key + "]");
      if (key == null || key.trim().length() == 0)
      {
        result.setStatus(IResult.FAILED);
        result.setFault(new WSMException("Invalid key"));
        if (debug)
        {
          System.out.println(mTag+"Invalid key");
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
      String serviceURL = ((IMessageContext) iContext).getServiceURL();
      if (debug) System.out.println(mTag+"serviceURL=[" + serviceURL+"]");
      // Get the message.
      //
      SOAPBindingMessageContext soapbindingmessagecontext =

 (SOAPBindingMessageContext) iContext;
      javax.xml.soap.SOAPMessage soapMessage =
 soapbindingmessagecontext.getRequestMessage();
      SOAPBody soapElem = soapMessage.getSOAPBody();
                                                    
      // As as point of interest, you can get the service URL. This could be used
      // by this class to know which service this message is bound for, and
 //therefore
      // which XPath expression to use.
      // In this example no such logic is needed as we only have one servcie
      // to worry about.
      //
      if (debug)
      {
        System.out.println(mTag+"----- Start ORIGINAL inbound message -----");
        ((XMLElement) soapElem).print(System.out);
        System.out.println(mTag+"-----  End ORIGINAL inbound message  -----");
      }
      // Create the XPath to reference the element which is to be encrypted.
      //
      String xpathStr = "/soap:Envelope/soap:Body/ns1:process/ns1:ccNum";
      
      // Build up a namespace list for any namespaces referenced by the
      // XPath expression. This will be the basis for a namespace context
      // created later.
      //
      final HashMap<String, String> namespaces = new HashMap<String, String>();
      namespaces.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
      namespaces.put("ns1", "http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel");
    
      // Extract the node that should be encrypted.
      //
      Node inputNode = getDataNode(soapElem, namespaces, xpathStr);
      if (inputNode == null)
      {
        // Something went wrong, but getDataNode() would've printed out a
 //stacktrace
        // so print out a debug statement and exit.
        //
        result.setStatus(IResult.FAILED);
        result.setFault(new WSMException("Cannot find node with XPath expression:
 "+xpathStr));
        if (debug)
        {
          System.out.println(mTag+"Cannot find node with XPath expression:
 "+xpathStr);
          System.out.println(mTag+DEBUG_END);
        }
        return result;
      }
    
      // Set a happy result.
      //
      result.setStatus(IResult.SUCCEEDED);
    }
    catch (Exception e)
    {
      // This is a general or catchall handler.
      //
      result.setStatus(IResult.FAILED);
      result.setFault(new WSMException(WSMException.FAULTCODE_QNAME_FAILED_CHECK,
 e));
      if (debug) System.out.println(this.getClass().getName()+": ERROR: Got an
 exception somewhere...");
    }
    
    if (debug) System.out.println(mTag+DEBUG_END);
    return result;
    
  } // execute()
  
} // OutboundDecryptor

3.3.4 カスタム・アサーション・エグゼキュータを使用したデータの暗号化

暗号化を行うサンプル・カスタム・アサーション・エグゼキュータを参照してください。

このサンプル・カスタム・アサーション・エグゼキュータを次に示します。

<orasp:Assertion xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
                          orawsp:Id="soa_encryption_template"
                          orawsp:attachTo="generic" orawsp:category="security"
                          orawsp:description="Custom Encryption of payload"
                          orawsp:displayName="Custom Encryption"
                          orawsp:name="custom/soa_encryption"
                          xmlns:custom="http://schemas.oracle.com/ws/soa/custom">
  <custom:custom-executor orawsp:Enforced="true" orawsp:Silent="false"
                   orawsp:category="security/custom"
                   orawsp:name="WSSecurity_Custom_Assertion">
    <orawsp:bindings>
      <orawsp:Implementation>owsm.custom.soa.InboundEncryptor</orawsp:Implementation>
      <orawsp:Config orawsp:configType="declarative" orawsp:name="encrypt_soa">
        <orawsp:PropertySet orawsp:name="encrypt">
          <orawsp:Property orawsp:contentType="constant"
                           orawsp:name="encryption_key" orawsp:type="string">
            <orawsp:Value>MySecretKey</orawsp:Value>
          </orawsp:Property>
          <orawsp:Property orawsp:contentType="constant"
                           orawsp:name="debugFlag" orawsp:type="string">
            <orawsp:Value>true</orawsp:Value>
          </orawsp:Property>
        </orawsp:PropertySet>
      </orawsp:Config>
    </orawsp:bindings>
  </custom:custom-executor>
</orasp:Assertion>

3.3.5 カスタム・アサーション・エグゼキュータを使用したデータの復号化

データを復号化するサンプル・カスタム・アサーション・エグゼキュータを参照してください。

復号用のサンプル・カスタム・アサーションを次に示します。

<orasp:Assertion xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
                          orawsp:Id="soa_decryption_template"
                          orawsp:attachTo="binding.client"
 orawsp:category="security"
                          orawsp:description="Custom Decryption of payload"
                          orawsp:displayName="Custom Decryption"
                          orawsp:name="custom/soa_decryption"
                          xmlns:custom="http://schemas.oracle.com/ws/soa/custom">
  <custom:custom-executor orawsp:Enforced="true" orawsp:Silent="false"
                   orawsp:category="security/custom"
                   orawsp:name="WSSecurity Custom Assertion">
    <orawsp:bindings>
      <orawsp:Implementation>owsm.custom.soa.OutboundDecryptor</orawsp:Implementation>
      <orawsp:Config orawsp:configType="declarative" orawsp:name="encrypt_soa">
        <orawsp:PropertySet orawsp:name="decrypt">
          <orawsp:Property orawsp:contentType="constant"
                           orawsp:name="decryption_key" orawsp:type="string">
            <orawsp:Value>MySecretKey</orawsp:Value>
          </orawsp:Property>
          <orawsp:Property orawsp:contentType="constant"
                           orawsp:name="debugFlag" orawsp:type="string">
            <orawsp:Value>true</orawsp:Value>
          </orawsp:Property>
        </orawsp:PropertySet>
      </orawsp:Config>
    </orawsp:bindings>
  </custom:custom-executor>
</orasp:Assertion>

3.3.6 コンポジット・アプリケーションを使用した暗号化されたメッセージの受信

暗号化された値を受信したことを示すためのBPELプロセスを含むサンプル・コンポジット・アプリケーションを参照してください。

このサンプル・コンポジット・アプリケーションを次に示します。

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Generated by Oracle SOA Modeler version 1.0 at [5/10/10 9:33 AM]. -->
<composite name="CustomEncryptionComposite"
           revision="1.0"
           label="2010-05-10_09-33-01_807"
           mode="active"
           state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
           xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionComposite/ProcessCustomer"
          location="ProcessCustomer.wsdl" importType="wsdl"/>
  <import namespace="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel"
          location="ExternalServiceBpel.wsdl" importType="wsdl"/>
  <service name="processcustomer_client_ep"
           ui:wsdlLocation="ProcessCustomer.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionComposite/ProcessCustomer#wsdl.interface(ProcessCustomer)"/>
    <binding.ws port="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionComposite/ProcessCustomer#wsdl.endpoint(processcustomer
_client_ep/ProcessCustomer_pt)">
      <wsp:PolicyReference URI="SOA/CustomEncryption" orawsp:category="security"
                           orawsp:status="enabled"/>
    </binding.ws>
  </service>
  <component name="ProcessCustomer">
    <implementation.bpel src="ProcessCustomer.bpel"/>
  </component>
  <reference name="ExternalSvc" ui:wsdlLocation="ExternalServiceBpel.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel#wsdl.interface(ExternalSe
rviceBpel)"/>
    <binding.ws port="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel#wsdl.endpoint(externalser
vicebpel_client_ep/ExternalServiceBpel_pt)"
                location="externalservicebpel_client_ep.wsdl"
                soapVersion="1.1">
      <wsp:PolicyReference URI="SOA/CustomDecryption" orawsp:category="security"
                           orawsp:status="enabled"/>
      <property name="weblogic.wsee.wsat.transaction.flowOption"
                type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>
  <wire>
    <source.uri>processcustomer_client_ep</source.uri>
    <target.uri>ProcessCustomer/processcustomer_client</target.uri>
  </wire>
  <wire>
    <source.uri>ProcessCustomer/ExternalSvc</source.uri>
    <target.uri>ExternalSvc</target.uri>
  </wire>
</composite>

3.3.7 コンポジット・アプリケーションを使用した復号化されたメッセージの受信

呼び出されている外部サービスを表し、復号化された値を受信したことを示すサンプル・コンポジット・アプリケーションを参照してください。

このサンプル・コンポジット・アプリケーションを次に示します。

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Generated by Oracle SOA Modeler version 1.0 at [5/10/10 9:41 AM]. -->
<composite name="CustomEncryptionExternalService"
           revision="1.0"
           label="2010-05-10_09-41-00_810"
           mode="active"
           state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
           xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel"
          location="ExternalServiceBpel.wsdl" importType="wsdl"/>
  <service name="externalservicebpel_client_ep"
           ui:wsdlLocation="ExternalServiceBpel.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel#wsdl.interface(ExternalSe
rviceBpel)"/>
    <binding.ws port="http://xmlns.oracle.com/CustomEncryption
_jws/CustomEncryptionExternalService/ExternalServiceBpel#wsdl.endpoint(externalser
vicebpel_client_ep/ExternalServiceBpel_pt)"/>
  </service>
  <component name="ExternalServiceBpel">
    <implementation.bpel src="ExternalServiceBpel.bpel"/>
  </component>
  <wire>
    <source.uri>externalservicebpel_client_ep</source.uri>
    <target.uri>ExternalServiceBpel/externalservicebpel_client</target.uri>
  </wire>
</composite>

3.4 カスタム・アサーションでのデータの暗号化と復号化の実行

カスタム・アサーションでデータの暗号化と復号化を実行するには、カスタム・アサーション・ポリシー・ファイルとJARファイルを作成し、カスタム・ポリシーをポリシー・ストアに追加し、CLASSPATHを更新して、最後にカスタム・ポリシーをWebサービスにアタッチします。

カスタム・アサーションでデータの暗号化と復号化を実行するには:

  1. 「カスタム・アサーションでのデータの暗号化と復号化」で説明したサンプル・コードを使用して、カスタム・アサーション・ポリシー・ファイルとカスタム・アサーション・エグゼキュータを作成します。これらのサンプルは次の主な機能を示しています。
    • 暗号化カスタム・アサーションの暗号化プロパティ・セットのプロパティencryption_keyとdebugFlagを指定します。

              <orawsp:PropertySet orawsp:name="encrypt">
                <orawsp:Property orawsp:contentType="constant"
                                 orawsp:name="encryption_key"
      orawsp:type="string">
                  <orawsp:Value>MySecretKey</orawsp:Value>
                </orawsp:Property>
                <orawsp:Property orawsp:contentType="constant"
                                 orawsp:name="debugFlag" orawsp:type="string">
                  <orawsp:Value>true</orawsp:Value>
                </orawsp:Property>
              </orawsp:PropertySet>
      

      詳細は、「カスタム・アサーションのパラメータの指定」を参照してください。

    • 復号化カスタム・アサーションの復号化プロパティ・セットのプロパティdecryption_keyとdebugFlagを指定します。

              <orawsp:PropertySet orawsp:name="decrypt">
                <orawsp:Property orawsp:contentType="constant"
                                 orawsp:name="decryption_key"
       orawsp:type="string">
                  <orawsp:Value>MySecretKey</orawsp:Value>
                </orawsp:Property>
                <orawsp:Property orawsp:contentType="constant"
                                 orawsp:name="debugFlag" orawsp:type="string">
                  <orawsp:Value>true</orawsp:Value>
                </orawsp:Property>
              </orawsp:PropertySet>

      詳細は、「カスタム・アサーションのパラメータの指定」を参照してください。

    • カスタム・アサーション・クラスから、定義済のネームスペースを含むXPath式で指定されたノードを抽出します。

      NamespaceContext ctx = new NamespaceContext()
            {
              public String getNamespaceURI(String prefix)
              {
                return namespaces.get(prefix);
              }
              // Dummy implementation - not used
              public Iterator getPrefixes(String val)
              {
                return null;
              }
              // Dummy implemenation - not used
              public String getPrefix(String uri)
              {
                return null;
              }
            };
            XPathFactory xpathFact = XPathFactory.newInstance();
            XPath xpath = xpathFact.newXPath();
            xpath.setNamespaceContext(ctx);
            
            node = (Node)xpath.evaluate(xpathStr, payload, XPathConstants.NODE);
          }
      
      

      詳細は、「XPathによるメッセージのパーツへのアクセス」を参照してください。

  2. 「カスタム・アサーションJARファイルの作成」の説明に従って、JARファイルを作成します。
  3. 「ポリシー・ストアへのカスタム・ポリシーの追加」の説明に従って、ポリシー・ストアにカスタム・ポリシーを追加します。
  4. 「カスタム・アサーションのデプロイ」の説明に従って、CLASSPATHを更新します。
  5. 「Webサービスへのカスタム・ポリシーのアタッチ」で説明した方法のいずれかを使用して、Webサービスにカスタム・ポリシーをアタッチします。

3.5 カスタム・アサーションでのユーザーの認証

認証カスタム・アサーションのサンプルは、WebLogic認証プロバイダを使用してユーザーを認証するために使用されます。資格証明(ユーザー名とパスワード)は着信メッセージから読み取られ、カスタム・ログイン・モジュールを使用して、WebLogic認証プロバイダに対して認証されます。

この項には次のトピックが含まれます:

3.5.1 カスタム・アサーション・エグゼキュータを使用した認証

認証を実行するカスタム・ログイン・モジュールを起動する方法については、サンプル・エグゼキュータを参照してください。

次の例では、これについて説明しています。

package sampleAssertion;
/**
 * <Description>
 * <p>
 * CustomAuthExecutor class. This class is invoked for custom_auth_policy
 * This class expects that wss_username_token_client_policy is attached to the 
* calling client
 * This class fetches credentials from incoming SOAP message and performs
 * authentication against a configured login module as specified by the Login 
* Config file.
 * </p>
 * </Description>
 * 
 */
import java.util.Iterator;
 
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
 
import oracle.wsm.common.sdk.IContext;
import oracle.wsm.common.sdk.IMessageContext;
import oracle.wsm.common.sdk.IResult;
import oracle.wsm.common.sdk.Result;
import oracle.wsm.common.sdk.SOAPBindingMessageContext;
import oracle.wsm.common.sdk.WSMException;
import oracle.wsm.policy.model.IAssertion;
import oracle.wsm.policy.model.ISimpleOracleAssertion;
import oracle.wsm.policyengine.impl.AssertionExecutor;
 
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
 
public class CustomAuthExecutor extends AssertionExecutor {
 
    public void init(IAssertion assertion,
        oracle.wsm.policyengine.IExecutionContext econtext,
        oracle.wsm.common.sdk.IContext context) {
        this.assertion = assertion;
        this.econtext = econtext;
    }
 
    public oracle.wsm.policyengine.IExecutionContext getExecutionContext() {
        return this.econtext;
    }
 
    public boolean isAssertionEnabled() {
        return ((ISimpleOracleAssertion) this.assertion).isEnforced();
    }
 
    public String getAssertionName() {
        return this.assertion.getQName().toString();
    }
 
 
    /**
     * <p>
     * This method is invoked for each request/response.
     * This method retrieves credentials from incoming soap message and 
     * authenticates 
     * them against a configured login module
     * </p>
     * @param context
     * @return IResult
     * @exception WSMException
     */
    @Override
    public IResult execute(IContext context) throws WSMException {
        oracle.wsm.common.sdk.IMessageContext.STAGE stage = ((oracle.wsm.common.sdk.IMessageContext) context)
            .getStage();
        IResult result = new Result();
 
        if (stage == IMessageContext.STAGE.request) {
            try {
                SOAPBindingMessageContext soapMsgCtxt= (SOAPBindingMessageContext)
                context;
                //Intercepts the incoming SOAP message
                SOAPMessage soapMessage = soapMsgCtxt.getRequestMessage();
                
                MyCallbackHandler callbackhandler = new MyCallbackHandler();
                
                //initialize CallbackHandler instance which is passed to 
                //LoginModule implementation
                initializeCallbackHandler(callbackhandler, soapMessage);
                
                
               //In order to authenticate a user, you first need a
               //javax.security.auth.login.LoginContext. 
               /**
 
               * Following parameters are passed to LoginContext
               * 1. name - LoginContext uses the name as the index into the JAAS
               * login configuration file to determine which LoginModules should 
               * be used. Such an entry specifies the class(es) that
               * implement the desired underlying authentication
               * technology(ies). The class(es) must implement 
               *  the LoginModule interface, which is in the
               * javax.security.auth.spi package.
               * In our case CustomLoginModule refers to
               * sampleAssertion.loginmodule.CustomLoginModule
               *
               * 2. Subject - the subject (javax.security.auth.Subject) to
               * authenticate. LoginContext passes the Subject
               * object to configured LoginModules so they may perform
               * additional authentication and update the Subject.
               *           
               * 3. CallbackHandler instance -
               * javax.security.auth.callback.CallbackHandler  object is used by
               * LoginModules to 
               * communicate with the user. LoginContext passes the
               * CallbackHandler object to configured LoginModules 
               *  so they may communicate with the user. An application
               * typically provides its own CallbackHandler implementation.
               * 
               **/
 
 
                // Obtain a LoginContext, needed for authentication. 
                // Tell it to use the LoginModule implementation 
               // specified by the entry named "CustomLoginModule" in the 
               // JAAS login configuration file and to also use the 
               // specified CallbackHandler.
                Subject subject = new Subject();
               LoginContext lc = new LoginContext("CustomLoginModule", subject,
               callbackhandler);
                
               /**Once the caller has instantiated a LoginContext, it invokes the
               * login method to authenticate a Subject
               * The LoginContext instantiates a new empty
               * javax.security.auth.Subject object (which represents the user or
               * service being
               * authenticated). 
               * The LoginContext constructs the configured LoginModule (in our
               * case CustomLoginModule) and initializes it with this new Subject
               * and
               * MyCallbackHandler.
               * The SampleLoginModule will utilize the MyCallbackHandler to
               * obtain the user name and password.
               * If authentication is successful, the CustomLoginModule
               * populates the Subject with a Principal representing the user. 
               * 
                **/
               lc.login();
                
               //authenticated Subject can be retrieved by calling the               
               // LoginContext's getSubject
                //method
                 subject = lc.getSubject();
 
 System.out.println("Authentication succeeded");

 context.setProperty(oracle.wsm.common.sdk.IMessageContext.SECURITY_SUBJECT,sub);                
                //sets result to succeeded if authentication succeeds
  result.setStatus(IResult.SUCCEEDED);
  } catch (LoginException e) {
               //in case there is a failure in authentication sets result to
               // failed state and
               // throw Failed authentication exception
                result.setStatus(IResult.FAILED);
                throw new WSMException(
                    WSMException.FAULTCODE_QNAME_FAILED_AUTHENTICATION, e);
            }
        }
 
        return result;
    }
 
                   /**
                    * Retrieves credentials from incoming SOAP message and 
                    * sets them into call back handler, which is than passed to
                    * Login module
                    * class
                    * via initialize(Subject, Callbackhandler,..) method of
                    *  LoginModule 
                    * @param SOAPMessage
                    * @param callbackhandler
                    * 
                    */
    private void initializeCallbackHandler(MyCallbackHandler callbackhandler,
 SOAPMessage soapElement) {
        try {
            SOAPHeader header = soapElement.getSOAPPart().getEnvelope()
                .getHeader();
            SOAPHeaderElement hdrElem = null;
            Iterator iter = header.examineAllHeaderElements();
            
            while (iter.hasNext()) {
                hdrElem = (SOAPHeaderElement) iter.next();
                String localName = hdrElem.getLocalName();
                NodeList headerNodeList = hdrElem.getChildNodes();
 
                for (int i = 0; i < headerNodeList.getLength(); i++) {
                    Node kid = headerNodeList.item(i);
                    String kidName = kid.getLocalName();
 
                    if (kidName.equals("UsernameToken")) {
                        NodeList nodeList = kid.getChildNodes();
                        
               /**check if incoming SOAP message contains UsernameToken
                *and retrieve credentials from it
               * The user name and password are set into callbackhandler
               * which are passed to Login module
                * for authentication
                **/
                        for (int j = 0; j < nodeList.getLength(); j++) {
                            String nodeName = nodeList.item(j).getLocalName();
                            String nodeValue = nodeList.item(j).getTextContent();
 
                            if (nodeName.equals("Username")) {
                                callbackhandler.setUserName(nodeValue);
                            }
 
                            if (nodeName.equals("Password")) {
                                callbackhandler.setPassword(nodeValue);
                            }
                        }
                        
                    }
                }
            }
 
        } catch (SOAPException se) {
            System.out.println("caught SOAPException: " + se.getMessage());
        }
        
    }
 
    /**
     *Executes any task required after policy execution.
     *
     */
    @Override
    public oracle.wsm.common.sdk.IResult postExecute(
        oracle.wsm.common.sdk.IContext context) {
        IResult result = new Result();
        result.setStatus(IResult.SUCCEEDED);
        return result;
    }        @Override
    public void destroy() {
    }
   }

3.5.2 ポリシー・ファイルを使用した認証

WebLogic認証プロバイダに対してユーザーを認証するために使用されるエグゼキュータを起動するサンプル・カスタム・アサーションを参照してください。

次のサンプルは、「カスタム・アサーション・エグゼキュータを使用した認証」で説明したエグゼキュータを呼び出すサンプル・カスタム・アサーションを示しています。これは、WebLogic認証プロバイダに対してユーザーを認証するために使用されます。

<?xml version = '1.0'?>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
 xmlns:oralgp="http://schemas.oracle.com/ws/2006/01/loggingpolicy"
 xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
orawsp:provides="{http://docs.oasis-open.org/ns/opencsa/sca/200903}authentication,
 {http://docs.oasis-open.org/ns/opencsa/sca/200903}clientAuthentication,
 {http://docs.oasis-open.org/ns/opencsa/sca/200903}clientAuthentication.message,
 {http://schemas.oracle.com/ws/2006/01/policy}token.usernamePassword"
 orawsp:status="enabled" xmlns="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-uti
lity-1.0.xsd" wsu:Id="custom_auth_policy"
orawsp:displayName="i18n:oracle.wsm.resources.policydescription.PolicyDescription
Bundle_oracle/custom_auth_policy_PolyDispNameKey"
 xmlns:orasp="http://schemas.oracle.com/ws/2006/01/securitypolicy"
orawsp:description="i18n:oracle.wsm.resources.policydescription.PolicyDescription
Bundle_oracle/custom_auth_policy_PolyDescKey" orawsp:attachTo="binding.server"
 Name="oracle/custom_auth_policy"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orawsp:category="security"
 orawsp:local-optimization="off">
   <orasp:custom-auth-assertion orawsp:Silent="false" orawsp:name="Custom auth"
 orawsp:Enforced="true" orawsp:category="security/authentication">
      <orawsp:bindings>
       <orawsp:Implementation>sampleAssertion.CustomAuthExecutor</orawsp:Implementation>
      </orawsp:bindings>
     </orasp:custom-auth-assertion>
</wsp:Policy>

3.5.3 ファイルを使用したユーザー認証の実装

ログイン構成ファイルを使用してユーザーを認証し、そのファイルで指定された様々なクラスを実装できます。

次の項目が含まれます。

3.5.3.1 ログイン構成ファイルを使用した認証

次のサンプルでは、ユーザー認証を実行するために使用されるログイン・モジュールを指定するエントリが含まれているログイン構成ファイルを示します。

/** Login Configuration for the Sample Application 
JAAS authentication is performed in a pluggable fashion, so Java applications can
 remain independent from 
underlying authentication technologies. Users can plugin there custom loginmodule
 implementations which 
can integrate with corresponding authentication provider.
 
The name for an entry in a login configuration file is the name that applications
 use to refer to the entry when 
they instantiate a LoginContext. The specified LoginModules (described below) are
 used to control the authentication process.
 
As part of this sample we are using CustomLoginModule and SimpleLoginModule
1. CustomLoginModule - integrates with weblogic authentication provider
2. SimpleLoginModule - simply returns
 
You can also provide implementation of javax.security.auth.login.Configuration
 interface
Refer http://download.oracle.com/javase/1.4.2/docs/api/javax/security/auth/login/Config
uration.html and 
http://download.oracle.com/javase/1.4.2/docs/guide/security/jaas/tutorials/LoginC
onfigFile.html for more details.
 
**/
 
CustomLoginModule {
   sampleAssertion.loginmodule.CustomLoginModule required debug=true;
};
 
SimpleLoginModule {
  sampleAssertion.loginmodule.SimpleLoginModule required debug=true;
};

3.5.3.2 カスタム・ログイン・モジュール・クラスの実装

javax.security.auth.spi.LoginModuleの実装を提供し、WebLogic認証プロバイダに対してユーザーを認証するサンプルのCustomLoginModuleクラスを参照してください。

次に、サンプルのCustomLoginModuleクラスを示します。このクラスは、「ログイン構成ファイルを使用した認証」のLoginConfigファイル内で指定されています。

package sampleAssertion.loginmodule;
/**
 * <Description>
 * <p>
 * CustomLoginModule class implements the javax.security.auth.spi.LoginModule
 * interface. CustomLoginModule class is specified 
 * by the login configuration file i.e Login.config file.
 * This class authenticates user against weblogic authentication provider. 
 * If authentication is successful, the CustomLoginModule associate Principals and
 * Credentials with the authenticated Subject
 * 
 * Users can create there own custom login modules
 * by implementing <code>javax.security.auth.spi.LoginModule</code> interface
 * </p>
 * </Description>
 * 
 */
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;
 
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
 
import weblogic.security.services.Authentication;
 
public class CustomLoginModule implements LoginModule
{
    private Subject authenticatorSubject;
    private CallbackHandler callbackHandler;
    private boolean loginSucceeded;
 
    /**
     * Initialize this LoginModule.
     *
     * <p> This method is called by the <code>LoginContext</code> to initialize 
     * the <code>LoginModule</code> with the relevant information.
     * <p>
     *
     * @param subject the - <code>javax.security.auth.Subject</code> to be
     * authenticated.
     *
     * @param callbackHandler - instance of
     * <code>javax.security.auth.callback.CallbackHandler</code>
     *   the CallbackHandler object is used by LoginModules to retrieve the
     * information set by the user
     *   e.g user name / password.
     * 
     * @param sharedState state shared with other configured LoginModules. <p>
     *
     * @param options options specified in the login Configuration for this
     *  particular LoginModule.
     *          
     **/
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
 Map<String, ?> sharedState, Map<String, ?> options)
    {
        this.authenticatorSubject = subject;
        this.callbackHandler = callbackHandler;
    }
 
 
    @Override
    /**
     * Method to authenticate a <code>Subject</code>.
     *
     * <p> The implementation of this method authenticates
     * a <code>Subject</code> using weblogic authentication provider
     * <p>
     *
     * @exception LoginException if the authentication fails
     *
     * @return true if the authentication succeeded
     */
    public boolean login() throws LoginException
    {
        /**authenticates user against weblogic authentication provider and sets
         * loginSucceeded
         * flag to true in case of successful authentication
         */
        this.authenticatorSubject = authenticate(this.callbackHandler);
        loginSucceeded = true;
        return loginSucceeded;
    }
    
    /**
     * authenticates using weblogic authentication provider
     * @param CallbackHandler
     * @return authenticated Subject
     * @throws LoginException
     */
    private Subject authenticate(CallbackHandler cbh) throws LoginException {
        try {
            return Authentication.login(cbh);
        } catch (LoginException e) {
            throw new LoginException("Authentication Failed"+e.getMessage());
        }
    }
 
    @Override
    /**
     * Method to commit the authentication process.
     *
     * <p> This method is called if the LoginContext's
     * overall authentication succeeded
     * <p>
     *
     * @exception LoginException if the commit fails
     *
     * @return true if this method succeeded, or false if this
     *          <code>LoginModule</code> should be ignored.
     */
    public boolean commit() throws LoginException {
        if (this.authenticatorSubject != null) {
            addToSubject(this.authenticatorSubject);
            return true;
        } else {
            return false;
        }
    }
    /**
     * Method to abort the authentication process.
     *
     * <p> This method is called if the LoginContext's
     * overall authentication failed.
     * <p>
     *
     * @exception LoginException if the abort fails
     *
     * @return true if this method succeeded, or false if this
     *          <code>LoginModule</code> should be ignored.
     */
    public boolean abort() throws LoginException {
        return this.loginSucceeded && logout();
    }
    
  
    /**
     * Method which logs out a <code>Subject</code>.  
     *
     * <p>An implementation of this method might remove/destroy a Subject's
     * Principals and Credentials.
     * <p>
     *
     * @exception LoginException if the logout fails
     *
     * @return true if this method succeeded, or false if this
     *          <code>LoginModule</code> should be ignored.
     */
    public boolean logout() throws LoginException
    {
        if (this.authenticatorSubject != null) {
            removeFromSubject(this.authenticatorSubject);
        }
        this.loginSucceeded = false;
        return true;
    }
    
    /**
     * associates relevant Principals and Credentials with the Subject located in
     * the LoginModule
     * @param Subject
     */
    protected void addToSubject(final Subject sub) {
        if (sub != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
               
             authenticatorSubject.getPrincipals().addAll(sub.getPrincipals());
 authenticatorSubject.getPrivateCredentials().addAll(sub.getPrivateCredentials());
authenticatorSubject.getPublicCredentials().addAll(sub.getPublicCredentials());
                        return null;
                    }
                });
        }
    }
    
    /**
     * removes Principals and Credentials from the subject
     * @param Subject
     */
    private void removeFromSubject(final Subject sub) {
        if (sub != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
 authenticatorSubject.getPrincipals().removeAll(sub.getPrincipals());
 authenticatorSubject.getPrivateCredentials().removeAll(sub.getPrivateCredentials(


));
authenticatorSubject.getPublicCredentials().removeAll(sub.getPublicCredentials());
                        return null;
                    }
                });
        }
    }
}

3.5.3.3 単純なログイン・モジュール・クラスの実装

javax.security.auth.spi.LoginModuleの実装を提供するサンプルのSimpleLoginModuleクラスを参照してください。

サンプルのSimpleLoginModuleクラスを次に示します。

/**
 * <Description>
 * <p>
 * SimpleLoginModule class implements the LoginModule interface. SimpleLoginModule
 * class is specified 
 * by the login configuration file i.e Loginconfig file.
 * This class simply returns true resulting in successful authentication.
 * 
 * This class is shown for illustration purpose only, users can integrate it with
 * there custom authentication provider
 * </p>
 * </Description>
 * 
 */
package sampleAssertion.loginmodule;
 
import java.util.Map;
 
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
 
public class SimpleLoginModule implements LoginModule {
 
    @Override
    public boolean abort() throws LoginException {
        return false;
    }
 
    @Override
    public boolean commit() throws LoginException {
        return true;
    }
 
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
        Map<String, ?> sharedState, Map<String, ?> options) {
        
    }
 
    @Override
    /**
     * This method simply returns true and results in successful authentication
     * Users can integrate it using there custom authentication provider
     */
    public boolean login() throws LoginException {
        System.out.println("Inside SimpleLoginModule");
        return true;
    }
 
    @Override
    public boolean logout() throws LoginException {
        return false;
    }
    
 
}

3.5.3.4 コールバック・ハンドラ・クラスの実装

javax.security.auth.callback.Callbackインタフェースの実装を提供するサンプルのCallbackHandlerクラスを参照してください。

サンプルのCallbackHandlerクラスを次に示します。

package sampleAssertion;
/**
 * <Description>
 * <p>
 * MyCallbackHandler class implements the 
 *  <code>javax.security.auth.callback.CallbackHandler </code> interface.  
 * An application implements its owm implementation of CallbackHandler.
 * An instance of CallbackHandler is passed as an argument to the LoginContext
 * instantiation. 
 * The LoginContext forwards the CallbackHandler directly to the underlying
 * LoginModules
 * so that they may interact with the application to retrieve specific
 * authentication data, 
 * such as usernames and passwords.
 * </p>
 * </Description>
 * 
 */
import java.io.IOException;
 
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
 
public class MyCallbackHandler implements CallbackHandler {
    
    private String userName = null;
    
    private String password = null;
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    /**
     * sets user name and password into callback
     */
    public void handle(Callback[] callbacks) throws IOException,
        UnsupportedCallbackException {
        
        for (int i = 0; i < callbacks.length; i++) {
            Callback c = callbacks[i];
            if (c instanceof NameCallback) {
                ((NameCallback) c).setName(this.userName);
            } else if (c instanceof PasswordCallback) {
                char[] password = this.password.toCharArray();
                ((PasswordCallback) c).setPassword(password);
            } else {
                throw new UnsupportedCallbackException(callbacks[i],
                    "Unrecognized Callback");
            }
        }
        
    }
 
}

3.6 カスタム・アサーションでのユーザー認証の実行

カスタム・アサーションでユーザー認証を実行するには、必要なファイルを作成し、ログイン構成ファイルを指定し、クライアントから認証のリクエストを起動します。

カスタム・アサーションでユーザー認証を実行するには:

  1. 「カスタム・アサーションでのユーザー認証」で説明したサンプル・コードを使用して、カスタム・アサーションとカスタム・アサーション・エグゼキュータを作成します。これらのサンプルは次の主な機能を示しています。
    • カスタム・アサーション実装クラスを定義します。

            <orawsp:bindings>    
      <orawsp:Implementation>sampleAssertion.CustomAuthExecutor
      </orawsp:Implementation>
            </orawsp:bindings>
      

      詳細は、「orawsp:Implementation」を参照してください

    • カスタム・アサーション・エグゼキュータの実行ステージを表示します。

      oracle.wsm.common.sdk.IMessageContext.STAGE stage =
       ((oracle.wsm.common.sdk.IMessageContext) context).getStage(); 
      

      詳細は、「OWSMカスタム・セキュリティ・アサーションへのアクセス」を参照してください。

    • ユーザーを認証するには、まず、javax.security.auth.login.LoginContextが必要です。LoginContextを取得します。JAAS構成ファイルのCustomLoginModuleという名前のエントリによって指定されたLoginModule実装を使用して、次のように指定されたCallbackHandlerを使用します。

      Subject subject = new Subject();
      LoginContext lc = new LoginContext("CustomLoginModule", subject,
      callbackhandler);
      

      呼出し側がLoginContextをインスタンス化すると、ログイン・メソッドを起動してサブジェクトを認証します。認証が正常終了した場合、CustomLoginModuleはユーザーを表すプリンシパルをサブジェクトに移入します。

      詳細は、http://download.oracle.com/javase/1.5.0/docs/guide/security/jgss/tutorials/index.htmlを参照してください。

      initializerCallbackHandler (「カスタム・アサーション・エグゼキュータを使用した認証」を参照)を使用して、着信SOAPメッセージにUsernameTokenが含まれているかどうかをチェックし、着信SOAPメッセージから資格証明を取得し、その資格証明をログイン・モジュール・クラスに渡します。

    • 成功した場合、結果に成功を設定します。

      result.setStatus(IResult.SUCCEEDED);
      
    • 失敗した場合、リクエストの実行が失敗した原因となるフォルトを設定します。

      result.setStatus(IResult.FAILED);
                      throw new WSMException(
                          WSMException.FAULTCODE_QNAME_FAILED_AUTHENTICATION, e);
      

      詳細は、「カスタム・アサーションでの例外処理」を参照してください。

  2. 「カスタム・アサーションJARファイルの作成」の説明に従って、JARファイルを作成します。
  3. 「ポリシー・ストアへのカスタム・ポリシーの追加」の説明に従って、ポリシー・ストアにカスタム・ポリシーを追加します。
  4. 「カスタム・アサーションのデプロイ」の説明に従って、CLASSPATHを更新します。
  5. 「Webサービスへのカスタム・ポリシーのアタッチ」で説明した方法のいずれかを使用して、Webサービスにカスタム・ポリシーをアタッチします。
  6. Webサービスのクライアントを作成します。このサンプル・カスタム・ポリシーは、クライアント側でwss_username_token_client_policyを使用します。wss_username_token_client_policyをクライアントに添付します。
  7. 構成ファイルと認証を実装するクラス・ファイルを作成します。このクラス・ファイルでは、「カスタム・ログイン・モジュール・クラスの実装」で説明したように認証を実装します。構成ファイルの詳細は、http://download.oracle.com/javase/1.5.0/docs/guide/security/jgss/tutorials/index.htmlのJAAS APIを参照してください。
  8. 「ログイン構成ファイルを使用した認証」で作成したログイン構成ファイルを指定します。次のいずれかの方法でファイルを指定できます。
    • WebLogic Serverを起動するために使用するスクリプトを編集し、javaコマンドの後に次のオプションを追加後、サーバーを再起動します。

      -Djava.security.auth.login.config==<LoginConfigファイルのパス>

    • Javaセキュリティ・プロパティ・ファイルは、<JAVA_HOME>/lib/security/java.securityという名前のファイルにあります。<JAVA_HOME>はJDKがインストールされたディレクトリを指しています。このファイルでは、"login.configuration.provider"セキュリティ・プロパティをログイン構成ファイルの完全修飾名に変更します。

  9. クライアントからリクエストを起動します。クライアントに設定されたユーザー名とパスワードは、WebLogic認証プロバイダと統合している設定済のログイン・モジュールに対して認証されます。