如何使用WildFly连接到Kerberos安全的Apache Phoenix数据源?

时间:2016-11-14 18:23:32

标签: jdbc jboss wildfly kerberos phoenix

我最近花了几周时间试图让WildFly成功连接到Kerberized Apache Phoenix数据源。有关如何执行此操作的文档数量惊人有限,但现在我已经破解了它,我正在分享。

环境:

  • WildFly 9+。一个等效的JBoss版本也可以工作(但未经测试)。 WildFly 8不包含所需的org.jboss.security.negotiation.KerberosLoginModule类(但您可以破解它,请参阅Kerberos sql server datasource in Wildfly 8.2)。我使用了WildFly 10.1.0.Final,并使用了独立部署。
  • Apache Phoenix 4.2.0.2.2.4.10。我还没有测试过任何其他版本。
  • Kerberos v5。我的KDC在Windows Active Directory上运行,但这不应该有明显的区别。
  • 我的Hadoop环境是HortonWorks版本,由Ambari维护。 Ambari确保所有配置文件和Kerberos实现设置都正确无误。

1 个答案:

答案 0 :(得分:0)

首先,您需要向WildFly的standalone.xml添加系统属性,以指定Kerberos配置文件的位置:

...
</extensions>

<system-properties>
    <property name="java.security.krb5.conf" value="/path/to/krb5.conf"/>
</system-properties>
...

我不打算在此处使用krb5.conf文件的格式,因为它取决于您自己的Kerberos实现。重要的是它包含KDC的默认领域和网络位置。在Linux上,您通常可以在/etc/krb5.conf/etc/security/krb5.conf找到它。如果您在Windows上运行WildFly,请确保在路径中使用正斜杠,例如"C:/Source/krb5.conf"

其次,向standalone.xml添加两个新的安全域 - 一个名为“Client”,由ZooKeeper使用,另一个名为“host”,由WildFly使用。不要问我为什么(它给我带来了太多痛苦)但是“客户端”安全域的名称必须匹配服务器上Zookeeper的JAAS客户端配置文件中定义的名称。如果您使用Ambari进行设置,则“客户端”是默认名称。另请注意,您不能简单地提供jaas.config文件作为系统属性,您必须在此处定义:

<security-domain name="Client" cache-type="default">
    <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required">
        <module-option name="useTicketCache" value="true"/>
        <module-option name="debug" value="true"/>
    </login-module>
</security-domain>
<security-domain name="host" cache-type="default">
    <login-module code="org.jboss.security.negotiation.KerberosLoginModule" flag="required" module="org.jboss.security.negotiation">
        <module-option name="useTicketCache" value="true"/>
        <module-option name="debug" value="true"/>
        <module-option name="refreshKrb5Config" value="true"/>
        <module-option name="addGSSCredential" value="true"/>
    </login-module>
</security-domain>

模块选项将根据您的实施情况而有所不同。我从默认的Java票证缓存中获取票证,该票证在JRE的java.security文件中定义,但如果需要,您可以在此处提供密钥表。请注意,将storeKey设置为true会破坏我的实施。查看Java文档以获取所有选项。请注意,每个安全域使用不同的登录模块:这不是偶然的 - Phoenix不知道如何使用org.jboss...版本。

现在您需要在org.apache.phoenix.jdbc.PhoenixDriver中为WildFly提供phoenix-<version>-client.jar类。在WildFly目录下创建以下目录树:

/modules/system/layers/base/org/apache/phoenix/main/

main目录中,粘贴您可以在服务器上找到的phoenix - client.jar(例如/usr/hdp/<version>/phoenix/client/bin)并创建module.xml文件:

<?xml version="1.0" ?>

<module xmlns="urn:jboss:module:1.1" name="org.apache.phoenix">

    <resources>
        <resource-root path="phoenix-<version>-client.jar">
            <filter>
                <exclude-set>
                    <path name="javax" />
                    <path name="org/xml" />
                    <path name="org/w3c/dom" />
                    <path name="org/w3c/sax" />
                    <path name="javax/xml/parsers" />
                    <path name="com/sun/org/apache/xerces/internal/jaxp" />
                    <path name="org/apache/xerces/jaxp" />
                    <path name="com/sun/jersey/core/impl/provider/xml" />
                </exclude-set>
            </filter>
        </resource-root>
        <resource-root path=".">
        </resource-root>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="sun.jdk"/>
        <module name="org.apache.log4j"/>
        <module name="javax.transaction.api"/>
        <module name="org.apache.commons.logging"/>
    </dependencies>
</module>

您还需要将hbase-site.xmlcore-site.xml从服务器粘贴到main目录中。这些通常位于/usr/hdp/<version>/hbase/conf/usr/hdp/<version>/hadoop/conf。如果你不添加这些,你会得到很多无用的ZooKeeper getMaster错误!如果您希望驱动程序登录到WildFly所在的位置,那么您还应该在log4j.xml目录中创建一个main文件。您可以在网络上的其他地方找到示例。 <resource-root path="."></resource-root>元素是在WildFly部署时将这些xml文件添加到类路径中的。

最后,在<subsystem xmlns="urn:jboss:domain:datasources:2.0">部分添加新的数据源和驱动程序。您可以使用CLI或直接编辑standalone.xml来执行此操作,我执行后者:

<datasource jndi-name="java:jboss/datasources/PhoenixDS" pool-name="PhoenixDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:phoenix:first.quorumserver.fqdn,second.quorumserver.fqdn:2181/hbase-secure</connection-url>
    <connection-property name="phoenix.connection.autoCommit">true</connection-property>
    <driver>phoenix</driver>
    <validation>
        <check-valid-connection-sql>SELECT 1 FROM SYSTEM.CATALOG LIMIT 1</check-valid-connection-sql>
    </validation>
    <security>
        <security-domain>host</security-domain>
    </security>
</datasource>
<drivers>
    <driver name="phoenix" module="org.apache.phoenix">
        <xa-datasource-class>org.apache.phoenix.jdbc.PhoenixDriver</xa-datasource-class>
    </driver>
</drivers>

使用适合您环境的正确ZooKeeper仲裁字符串替换first.quorumserver.fqdn,second.quorumserver.fqdn非常重要。您可以在HBase配置目录hbase-site.xml中的hbase.zookeeper.quorum中找到它:hbase-site.xml您无需将Kerberos信息添加到连接URL字符串!

<强> TL;博士

  • 确保{class 1}}和core-site.xml在您的类路径中。
  • 确保您拥有一个名为ZooKeeper所期望的<security-domain>(可能是“客户”),该名称使用com.sun.security.auth.module.Krb5LoginModule
  • Phoenix连接URL 必须包含整个ZooKeeper仲裁。你不能错过一个服务器!确保它与hbase-site.xml
  • 中的值相匹配

<强>参考文献: