**所以,我想有一种方法可以通过 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 都不是很了解。
谢谢阅读。