8

我有一个简单的基于 Thrift 的 java 应用程序。它真的非常简单,只不过是在 java 中使用 Thrift 进行“Hello World”消息传输。有人告诉我,我需要在我的消息中添加 Kerberos 支持。我做了一些谷歌搜索,很惊讶 Thrift 还没有某种形式的 Kerberos 支持(或者如果有,我找不到它)。我考虑过使用 GSSAPI 编写自己的包装器,但我无法包装/解开我的 Thrift 消息,因为这会破坏 Thrift 消息格式。

有没有人曾经使用 Kerberized Thrift?.. 或者知道它会怎么做?

提前致谢。

4

1 回答 1

15

**所以,我想有一种方法可以通过 SASL/GSS API 来做到这一点。这让我很困惑,为什么我在互联网上的任何地方都看不到任何很好的例子。但是,我发布了一个我创建的示例,希望它对其他人有所帮助......或者有人可以纠正我在这里做一些有用的事情的错觉。

示例服务器代码:

TServerSocket serverTransport = new TServerSocket(7911);  // new server on port 7911
HelloWorldService.Processor<Iface> processor = new HelloWorldService.Processer<Iface>(new ThriftServerImpl());  // This is my thrift implementation for my server
Map<String, String> saslProperties = new HashMap<String, String>();  // need a map for properties
saslProperties.put(Sasl.QOP, "true");
saslProperties.put(Sasl.QOP, "auth-conf");  // authorization and confidentiality

TSaslServerTransport.Factory saslTransportFactory = new TSaslServerTransport.Factory();     // Creating the server definition
saslTransportFactory.addServerDefinition(
            "GSSAPI",       //  tell SASL to use GSSAPI, which supports Kerberos
            "myserviceprincipal",   //  base kerberos principal name - myprincipal/my.server.com@MY.REALM 
            "my.server.com",    //  kerberos principal server - myprincipal/my.server.com@MY.REALM
            saslProps,      //  Properties set, above
            new SaslRpcServer.SaslGssCallbackHandler()));  //  I don't know what this really does... but I stole it from Hadoop and it works.. so there.

Tserver server = new TThreadPoolServer(newTThreadPoolSErver.Args(serverTransport).transportFactory(saslTrasnportFactory).processor(processor));

server.serve();   // Thrift server start

示例客户端代码

TTransport transport = new TSocket("my.server.com", 7911);   // client to connect to server and port
saslProperties.put(Sasl.QOP, "true");
saslProperties.put(Sasl.QOP, "auth-conf");  // authorization and confidentiality

TTransport saslTransport = new TSaslTransport(
            "GSSAPI",       //  tell SASL to use GSSAPI, which supports Kerberos
            null,           //  authorizationid - null
            "myserviceprincipal",   //  base kerberos principal name - myprincipal/my.client.com@MY.REALM 
            "my.server.com",    //  kerberos principal server - myprincipal/my.server.com@MY.REALM
            saslProps,      //  Properties set, above
            null,           //  callback handler - null
            transport);     //  underlying transport

TProtocol protocol = new TBinaryProtocol(saslTransport);    // set up our new Thrift protocol

HelloWorldService.Client client = new HelloWorldService.Client(protocol);   // Setup our thrift client
saslTransport.open();

String response = client.hello("Hi There");   // send message

System.out.println("response = " + response);

transport.close();

其他注意事项:

* 我在客户端和服务器上都设置了几个 java 属性。
- java.security.krb5.realm = MY.REALM // 领域名称
- java.security.krb5.kdc = my.kdc.com // kdc 服务器
- javax.security.auth.useSubjectCredsOnly = false // 允许 JAAS 获取TGT。
- java.security.auth.login.config = /etc/myapp/conf/jaas.conf - 需要的 jaas 文件
- sun.security.krb5.debug = true // 帮助诊断问题。
* 上面指定的 jaas.conf 文件需要有两个条目(每个服务器可能只有一个......)。我不记得我是从哪里收集到这些信息的……但这是我的文件:

com.sun.security.jgss.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="/etc/myapp/conf/myapp.keytab"
    useTicketCache=true
    principal="myuserprincipal"
    debug=true;
};

com.sun.security.jgss.accept {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="/etc/myapp/conf/myapp.keytab"
    useTicketCache=false
    principal="myserviceprincipal/my.server.com"
    debug=true;
};

(回到考虑....)
* 尽管 Sasl.QOP 为“auth-conf”.. 传输的第一个(?)消息未加密。也许这只是握手之类的。其余消息似乎已加密,但第一个消息向控制台打印了一条丑陋的消息“对等方未执行加密”。最好不要收到该消息,因为它会在未来引起悲伤(无论是否有根据)。

无论如何,我希望这对某人有所帮助......或者可以引发一些对我有帮助的改进。:) 很难相信我花了 2-3 天的时间来做这件事,而且只产生了少量的代码,但是当我开始的时候,我对 Kerberos 和 Thrift 都不是很了解。

谢谢阅读。

于 2012-12-12T12:30:25.793 回答