开发 customPasswordEncryption 提供者

可以开发 customPasswordEncryption 提供者以对 Java™ 平台企业修订版 (J2EE) 应用程序制定定制授权决策,方法是实现 Liberty 服务器中提供的 com.ibm.wsspi.security.crypto.CustomPasswordEncryption 接口。

关于此任务

注: 下列可选步骤用于支持命令行实用程序。如果提供者计划仅支持服务器运行时环境,那么可以跳过这些步骤。
customPassworedEncryption 提供者由下列三个文件组成:
  • OSGi 捆绑软件文件,其中包含可执行文件。
  • 功能部件清单文件,用于定义 customPasswordEncryption 提供者的用户功能部件。此文件包含所需捆绑软件的位置和功能部件的属性,以及扩展清单文件(如果已打包该文件)。此信息供服务器运行时使用。
  • 扩展清单文件,用于定义 customPasswordEncryption 提供者所需的捆绑软件文件和实现类名。此文件是可选文件,必须具有此文件才能支持命令行实用程序。

过程

  1. 创建 OSGi 组件,该组件提供用于实现 com.ibm.wsspi.security.crypto.CustomPasswordEncryption 接口的服务。

    CustomPasswordEncryption 接口定义以下三种方法:decryptLiberty 服务器运行时调用该方法以对字符串解密)、encryptLiberty 服务器运行时调用该方法以对字符串加密)和 initialize(保留供将来使用)。

    以下示例使用 OSGi 声明式服务注释:
    package com.mycompany.custom;
    
    import org.osgi.service.component.ComponentContext;
    import org.osgi.service.component.annotations.Activate;
    import org.osgi.service.component.annotations.Component;
    import org.osgi.service.component.annotations.ConfigurationPolicy;
    import org.osgi.service.component.annotations.Deactivate;
    import org.osgi.service.component.annotations.Modified;
    
    import com.ibm.wsspi.security.crypto.CustomPasswordEncryption;
    import com.ibm.wsspi.security.crypto.EncryptedInfo;
    import com.ibm.wsspi.security.crypto.PasswordDecryptException;
    import com.ibm.wsspi.security.crypto.PasswordEncryptException;
    
    /**
     */
    @Component(service = CustomPasswordEncryption.class,
                    immediate = true,
                    name = "com.mycompany.CustomPasswordEncryptionImpl",
                    configurationPolicy = ConfigurationPolicy.OPTIONAL,
                    property = { "someKey=someValue" })
    public class CustomPasswordEncryptionImpl implements CustomPasswordEncryption {
    
        @Activate
        protected synchronized void activate(ComponentContext cc, Map<String, Object> props) {
        }
    
        @Modified
        protected synchronized void modify(Map<String, Object> props) {
        }
    
        @Deactivate
        protected void deactivate(ComponentContext cc) {
        }
    
        /**
         * The encrypt operation takes a UTF-8 encoded String in the form of a byte[].
         * The byte[] is generated from String.getBytes("UTF-8"). An encrypted byte[]
         * is returned from the implementation in the EncryptedInfo object.
         * Additionally, a logically key alias is returned in EncryptedInfo so which
         * is passed back into the decrypt method to determine which key was used to
         * encrypt this password. The WebSphere Application Server runtime has no
         * knowledge of the algorithm or key used to encrypt the data.
         * 
         * @param decrypted_bytes
         * @return com.ibm.wsspi.security.crypto.EncryptedInfo
         * @throws com.ibm.wsspi.security.crypto.PasswordEncryptException
         **/
        @Override
        public EncryptedInfo encrypt(byte[] input) throws PasswordEncryptException {
            byte[] output = null;
            String key = null;
            try {
                :
                <do some encryption>
                :
                return new EncryptedInfo(output, key);
            } catch (Exception e) {
                throw new PasswordEncryptException("Exception is caught", e);
            }
        }
    
        /**
         * The decrypt operation takes the EncryptedInfo object containing a byte[]
         * and the logical key alias and converts it to the decrypted byte[]. The
         * WebSphere Application Server runtime will convert the byte[] to a String
         * using new String (byte[], "UTF-8");
         * 
         * @param info
         * @return byte[]
         * @throws PasswordEncryptException
         * @throws com.ibm.wsspi.security.crypto.PasswordDecryptException
         **/
        @Override
        public byte[] decrypt(EncryptedInfo info) throws PasswordDecryptException {
            byte[] input = info.getEncryptedBytes();
            String key = info.getKeyAlias();
            byte[] output = null;
            try {
                :
                <do some decryption>
                :
                return output;
            } catch (Exception e) {
                throw new PasswordEncryptException("Exception is caught", e);
            }
        }
    
        /**
         * This is reserved for future use and is currently not called by the
         * WebSphere Application Server runtime.
         * 
         * @param initialization_data
         **/
        @SuppressWarnings("rawtypes")
        @Override
        public void initialize(Map initialization_data) {}
    
    }
  2. 将该组件封装到作为用户功能部件的组成部分的 OSGi 捆绑软件中。确保该捆绑软件包含 OSGi 服务清单。
    以下示例显示 OSGi 服务清单的内容:
    <?xml version="1.0" encoding="UTF-8"?>
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.mycompany.custom.CustomPasswordEncryptionImpl" configuration-policy="optional" immediate="true" activate="activate" deactivate="deactivate" modified="modify">
      <implementation class="com.mycompany.custom.CusomPasswordEncryptionImpl"/>
      <service>
        <provide interface="com.ibm.wsspi.security.crypto.CustomPasswordEncryption"/>
      </service>
      <property name="<someKey>" type="String" value="<someValue>"/>
    </scr:component>
  3. 确保您的功能部件清单文件包含带有 start-phase:="SERVICE_EARLY" 的 OSGi 子系统内容。如果完成了该可选步骤,那么扩展清单文件的位置位于 Subsystem-Content 头中。 例如:
    Manifest-Version: 1.0
    IBM-Feature-Version: 2
    IBM-ShortName: customPasswordEncryption-1.0
    Subsystem-Type: osgi.subsystem.feature
    Subsystem-Version: 1.0.0
    Subsystem-ManifestVersion: 1.0
    Subsystem-SymbolicName: customPasswordEncryption-1.0;visibility:=public
    Subsystem-Content: 
    com.mycompany.custom; version="[1,1.0.100)"; start-phase:="SERVICE_EARLY", customEncryption.jar; type=file; \
    location:="bin/tools/extensions/ws-customPasswordEncryption/customEncryption.jar"
    Subsystem-Description: MyCompany custom password encryption
  4. 将功能部件安装到用户产品扩展位置之后,使用功能部件名称来配置 server.xml 文件。
    <featureManager>
       ...
       <feature>usr:customPasswordEncryption-1.0</feature>
    </featureManager>

    要验证安装对于服务器运行时环境是否成功,请验证 message.log 文件中是否记录了 CWWKS1850I 消息。

  5. 可选:创建扩展清单文件,该文件是将 customPasswordEncryption 提供者插入到命令行实用程序(例如 SecurityUtility)中所必需的。扩展清单文件是一个包含 MANIFEST.MF 文件的 JAR 文件。扩展清单需要的头如下:
    • Require-Bundle:定义需要装入的捆绑软件的列表。格式与 OSGi 捆绑软件清单文件相同。
    • IBM-ImplementationClass:定义用于实现 com.ibm.wsspi.security.crypto.CustomPasswordEncryption 接口的实现类。

    下面是 MANIFEST.MF 文件的示例:

    Require-Bundle: com.mycompany.custom; version="[1,1.0.100)"; location="usr/extension/lib"
    IBM-ImplementationClass: com.mycompany.custom.CusomPasswordEncryptionImpl
    使用 jar 命令来打包扩展清单文件。例如:
    jar cfm customEncryption.jar MANIFEST.MF

    将该 JAR 文件放在 wlp/bin/tools/extensions/ws-customPasswordEncryption 中。 请确保扩展清单文件的位置在功能部件清单文件的 Subsystem-Content 头部分中。

    需要将这些文件放在特定目录中。下图描述这些文件之间的关系:
    图 1. customPassworedEncryption 提供者文件此流程图描述文件与其目录之间的关系。
  6. 可选:如果完成了步骤 5,那么可以通过使用以下命令行实用程序命令来验证安装是否成功:
    wlp/bin/securityUtility encode --listCustom
    期望的输出是 customPasswordEncryption 的信息。例如:
    [{"name":"custom","featurename":"usr:customPasswordEncryption-1.0","description":"MyCompany custom password encryption"}]

    请确保所有所需的文件存在以及这些文件的内容准确。


用于指示主题类型的图标 任务主题

文件名:twlp_developing_custom_passwd_encrypt.html