現在地: EMS の構成 > ソフトウェアダウンロードのための輸出コンプライアンス

ソフトウェアダウンロードのための輸出コンプライアンス

輸出コンプライアンス

世界中のソフトウェアパブリッシャーは、アプリケーションをソフトウェアダウンロードの形態で配布しています。世界各国はソフトウェアの輸出を規制する政策を定めています。それらの政策の目的は、セキュリティを強化し、無許可の組織によるソフトウェアの配布を制限することです。世界各国で自社ソフトウェアの販売を希望するソフトウェアパブリッシャーは、法令を順守し法的問題を回避しなければなりません。ソフトウェア輸出政策の実施は「輸出コンプライアンス」と呼ばれます。

Sentinel EMS による輸出コンプライアンス

Sentinel EMSポータルでは、ダウンロード定義を作成してプロダクトにリンクさせることができます。プロダクトをダウンロード配布する ISVやチャネルパートナーは、ソフトウェアの輸出を規制するポリシーを適用できます。Sentinel EMS では、ISV やチャネルパートナーが顧客に対してソフトウェア輸出コンプライアンスを実施するための Java インターフェースを実装できます。

輸出コンプライアンスのための Sentinel EMS のインターフェース

Sentinel EMS には、輸出コンプライアンスを実施するための ExportComplianceHandler インターフェースが用意されています。ソフトウェア輸出コンプライアンスは特定のカテゴリのソフトウェアには必須であり、その実施ルールと規制は各機関ごとに異なります。ExportComplianceHandler インターフェースは、次のどちらかまたは両方のレベルにおいて輸出コンプライアンスを実施するメソッドを提供します。

ExportComplianceHandler インターフェースは次のように定義されます。

package com.sfnt.ems.service;


import com.sfnt.ems.util.EMSException;

public interface ExportComplianceHandler {
	
	String exportComplianceAtLogin(String xml) throws EMSException;
	
	String exportComplianceAtProductDownload(String xml) throws EMSException;

}

ExportComplianceHandler インターフェースのメソッドは次のとおりです。

Sentinel EMS には ExportComplianceHandler インターフェースのインプリメンテーションのサンプルとして、ExportComplianceHandlerImpl が用意されています。このインプリメンテーションに変更を加えるか、ExportComplianceHandler インターフェースの独自のインプリメンテーションを別個の Java ファイルに記述してそのクラスファイルを生成してください。インプリメンテーションの記述方法については、 ExportComplianceHandler インターフェースのインプリメントを参照してください。

exportComplianceAtLogin() の入力用 XSD

ExportComplianceHandler インターフェースの exportComplianceAtLogin(String xml) メソッドは、入力としてパラメータ String xml を受け入れます。このパラメータは複数の属性が含まれた XML 文字列で、ログインレベルで使用して輸出コンプライアンスを実施できます。exportComplianceAtLogin() メソッドの XML 文字列パラメータ用の XSD は次のとおりです。

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="exportCompliance">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="userRequestHeader">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="header" maxOccurs="unbounded" minOccurs="0">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:string" name="value" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="loggedinUserDetail"  minOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="loginId"/>
              <xs:element type="xs:string" name="name"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element type="xs:string" name="PKID"/>
        <xs:element type="xs:string" name="EID"/>
        <xs:element name="customer" minOccurs="0" maxOccurs="1">
          <xs:complexType >
            <xs:sequence>
              <xs:element type="xs:string" name="name"/>
              <xs:element type="xs:string" name="customerCRMId"/>
              <xs:element type="xs:string" name="refId"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="contact" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="contactEmail"/>
              <xs:element type="xs:string" name="contactName"/>
              <xs:element type="xs:string" name="contactNumber"/>
              <xs:element name="locale">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="countryCode"/>
                    <xs:element type="xs:string" name="localeDisplayName"/>
                    <xs:element type="xs:string" name="localeCode"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element type="xs:string" name="refId1"/>
              <xs:element type="xs:string" name="refId2"/>
              <xs:element type="xs:string" name="shipAddr"/>
              <xs:element type="xs:string" name="shipAddrCity"/>
              <xs:element type="xs:string" name="shipAddrState"/>
              <xs:element type="xs:string" name="shipAddrCountry"/>
              <xs:element type="xs:string" name="shipAddrZip"/>
              <xs:element type="xs:string" name="billAddr"/>
              <xs:element type="xs:string" name="billAddrCity"/>
              <xs:element type="xs:string" name="billAddrState"/>
              <xs:element type="xs:string" name="billAddrCountry"/>
              <xs:element type="xs:string" name="billAddrZip"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>        
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

validateDownloadForProduct() の入力用 XSD

ExportComplianceHandler インターフェースの exportComplianceAtProductDownload(String xml) メソッドは、入力としてパラメータ String xml を受け入れます。このパラメータは輸出コンプライアンスをプロダクトレベルで判定するために使用されます。exportComplianceAtProductDownload() メソッドにパラメータとして渡される XML 用の XSD は次のとおりです。

 <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="exportCompliance">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="userRequestHeader">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="header" maxOccurs="unbounded" minOccurs="0">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="name" use="optional"/>
                      <xs:attribute type="xs:string" name="value" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="loggedinUserDetail" minOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="loginId"/>
              <xs:element type="xs:string" name="name"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element type="xs:string" name="PKID"/>
        <xs:element type="xs:string" name="EID"/>
        <xs:element name="customer" maxOccurs="1" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="name"/>
              <xs:element type="xs:string" name="customerCRMId"/>
              <xs:element type="xs:string" name="refId"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="contact" maxOccurs="1" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="contactEmail"/>
              <xs:element type="xs:string" name="contactName"/>
              <xs:element type="xs:string" name="contactNumber"/>
              <xs:element name="locale">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="countryCode"/>
                    <xs:element type="xs:string" name="localeDisplayName"/>
                    <xs:element type="xs:string" name="localeCode"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element type="xs:string" name="refId1"/>
              <xs:element type="xs:string" name="refId2"/>
              <xs:element type="xs:string" name="shipAddr"/>
              <xs:element type="xs:string" name="shipAddrCity"/>
              <xs:element type="xs:string" name="shipAddrState"/>
              <xs:element type="xs:string" name="shipAddrCountry"/>
              <xs:element type="xs:string" name="shipAddrZip"/>
              <xs:element type="xs:string" name="billAddr"/>
              <xs:element type="xs:string" name="billAddrCity"/>
              <xs:element type="xs:string" name="billAddrState"/>
              <xs:element type="xs:string" name="billAddrCountry"/>
              <xs:element type="xs:string" name="billAddrZip"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="product" minOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="productName"/>
              <xs:element type="xs:string" name="productVersion"/>
              <xs:element type="xs:string" name="refId1"/>
              <xs:element type="xs:string" name="refId2"/>
              <xs:element type="xs:string" name="externalId"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema> 

ExportComplianceHandler インターフェースのインプリメント

Sentinel EMSには、ExportComplianceHandler インターフェースのサンプルとして ExportComplianceHandlerImpl が用意されています。このサンプルに変更を加えるか、輸出コンプライアンスを実施するための独自のインプリメンテーションを記述してください。

インターフェースのメソッドのオーバライド

ExportComplianceHandler インターフェースは、2つのメソッド exportComplianceAtLogin() および exportComplianceAtProductDownload() を提供します。これらのメソッドは、輸出コンプライアンスを実施するためのインプリメンテーションの中でオーバライドできます。次の例はサンプルインプリメンテーション ExportComplianceHandlerImpl からの抜粋で、exportComplianceAtLogin() メソッドがオーバライドされています。

public class ExportComplianceHandlerImpl implements ExportComplianceHandler {

	private final Log log = LogFactory.getLog(this.getClass());
	private DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	
	
	private Document getRequestData(String xml)	
throws ParserConfigurationException, SAXException, IOException, UnsupportedEncodingException { DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse
(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-16")))); return document; } @Override public String exportComplianceAtLogin(String xml) throws EMSException { StringBuffer responseXml = new StringBuffer(); boolean status = true; String message = ""; try{ Document document = getRequestData(xml); Element docElement = document.getDocumentElement(); NodeList node = docElement.getChildNodes(); if (node != null && node.getLength() > 0) { for (int i = 0; i < node.getLength(); i++) { if (node.item(i).getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node.item(i); validateCompliance(element,status,message); } } } }catch (Exception ex) { log.error(ex); message=ex.getMessage(); //status is false in case of exception status=false; } responseXml.append("<"+DownloadConstants.EXPORT_COMPLIANCE_RESULT_TAG+">" +"<"+DownloadConstants.EXPORT_COMPLIANCE_STATUS_TAG+">"); responseXml.append(status); responseXml.append
("</"+DownloadConstants.EXPORT_COMPLIANCE_STATUS_TAG+">" +"<"+DownloadConstants.EXPORT_COMPLIANCE_MESSAGE_TAG+">"); responseXml.append(message); responseXml.append
("</"+DownloadConstants.EXPORT_COMPLIANCE_MESSAGE_TAG+">"

+"</"+DownloadConstants.EXPORT_COMPLIANCE_RESULT_TAG+">"); return responseXml.toString(); }

上のサンプルコードで、オーバライドされたメソッド exportComplianceAtLogin()validateCompliance() を呼び出しています。これはユーザ定義のメソッドです。

ユーザ定義のメソッド

上記のサンプルコードで、オーバライドされたメソッド exportComplianceAtLogin() はユーザ定義のメソッド validateCompliance() を呼び出しています。このユーザ定義のメソッドには、輸出コンプライアンスを実施するためにバリデーションを実行するロジックが含まれています。このユーザ定義のメソッドは次のとおりです。

private void validateCompliance(Element element,boolean status, String message) {
		//customer
/*		if (element.getNodeName()!=null && element.getNodeName().contains("customer")) {
		    String customerName = element.getElementsByTagName
("name").item(0).getTextContent(); String crmID = element.getElementsByTagName
("customerCRMId").item(0).getTextContent(); if (customerName.equals("not to be exported")|| crmID.equals("0001q421")
||crmID.equals("0001q425")){ status=false; message="download not allowed to this customer"; } // Header }else if (element.getNodeName()!=
null && element.getNodeName().contains("userRequestHeader")) { NodeList headerList = element.getChildNodes(); if(headerList != null && headerList.getLength() > 0) { for (int i = 0; i < headerList.getLength(); i++) { if (headerList.item(i).getNodeType() == Node.ELEMENT_NODE) { Element headerElement = (Element)headerList.item(i); if (headerElement.getAttribute("name").equals("host")
&& headerElement.getAttribute("value").equals("not to be exported")){ status=false; message=
"download not allowed to this customer"; } } } } */ /* //Product level }else if (element.getNodeName()!=null &&
element.getNodeName().contains("product")) { String productName =
element.getElementsByTagName("productName").item(0).getTextContent(); if (productName.equals("not to be exported")){ status=false; message="download not allowed to this customer"; } }*/ //... more checks as per need }

このメソッドが含まれたサンプルコードはコメント化されており、顧客レベルおよびプロダクトレベルで使用してデータをバリデーションします。コメント解除して変更を加えたり、独自のロジックを記述したりできます。

XML 入力文字列を構築するメソッド

サンプルコードでは、別のメソッド getUserRequestHeader() も使用されています。このメソッドは、メソッド exportComplianceAtLogin() および exportComplianceAtProductDownload() で使用される XML 入力文字列を構築します。サンプルコードで、このメソッドはリクエストパラメータの値を取得することにより、XML 属性 <userRequestHeader> を構築します。XML 属性 <userRequestHeader> は、exportComplianceAtLogin() にパラメータとして渡される XML 文字列の一部です。メソッド getUserRequestHeader() を使用すると、取得したリクエストパラメータを使用して XML 文字列を構築できます。

public static Map<String, String> getUserRequestHeader(HttpServletRequest request){
		Map<String, String> requestHeaders = new HashMap<String, String>();
		Enumeration<String> headerNames = request.getHeaderNames();
	    while(headerNames.hasMoreElements()) {
	      String headerName = (String)headerNames.nextElement();
	      //decide if this header need to be included and add it to xml
	      requestHeaders.put(headerName,request.getHeader(headerName));
	    }
	    // remove whatever is extra/not required
	    // session token and therefore excluded
	    requestHeaders.remove("referer");
	    
	    //other parameter from request
	    requestHeaders.put("remoteAddress",request.getRemoteAddr());
	    requestHeaders.put("remoteHost",request.getRemoteHost());
	    requestHeaders.put("remotePort", String.valueOf(request.getRemotePort())); 
	    requestHeaders.put("protocol", request.getProtocol());

	    return requestHeaders;    
	}

ExportComplianceHandler インターフェースのインプリメントに関する重要事項:

出力用 XSD

DownloadHandler インターフェースの 2 つのメソッド exportComplianceAtLogin(String xml) および exportComplianceAtProductDownload(String xml) は、出力として String xml を返します。 返される XML 文字列用の XSD は次のとおりです。

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="exportComplianceResult" minOccurs="1">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="status"/>
        <xs:element type="xs:string" name="message"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema> 

出力される XML 文字列は <status> 属性の値の値を返します。サンプルコードで、<status> によって返される値は次のとおりです。

ダウンロードログの管理

ダウンロードアクティビティに関するログがテーブル T_USER_LOG に作成されます。Sentinel EMSポータルには、カスタムレポートのオプションがあります。このオプションを使用して、輸出コンプライアンスのログに 関するレポートを定義して生成できます。カスタムレポートの生成方法については、『Sentinel EMS 2.8 User's Guide』を参照してください。

Sentinel EMS が WebLogic 上にデプロイされている場合、カスタマイズを行うためには ems.war ファイルを生成してデプロイしなければなりません。 WebLogic の場合の .war ファイルの生成を参照してください。

 

  http://www.safenet-inc.com/Support
  © Copyright 2013, SafeNet, Inc. All rights reserved.