Kerberos для экономии?

У меня есть простое Java-приложение на основе Thrift, которое я написал. Это действительно очень просто, не намного больше, чем передача сообщений «Hello World» с использованием Thrift в java. Мне сказали, что мне нужно добавить поддержку Kerberos в мое сообщение. Я погуглил и удивился, что Thrift еще не имеет поддержки Kerberos в той или иной форме (а если и есть, то я не могу ее найти). Я думал написать свою собственную оболочку с использованием GSSAPI, но я не могу обернуть/развернуть свое сообщение Thrift, так как это портит формат сообщения Thrift.

Кто-нибудь когда-нибудь использовал Kerberized Thrift?.. или знает, как это сделать?

Заранее спасибо.


person Wanderer    schedule 10.12.2012    source источник
comment
Похоже, что Hadoop мог что-то сделать с этим...   -  person Wanderer    schedule 10.12.2012


Ответы (1)


**Полагаю, есть способ сделать это через API SASL/GSS. Меня смущает, почему я нигде не вижу хороших примеров этого в Интернете. Тем не менее, я публикую пример того, что я создал, в надежде, что он поможет другим... или что кто-то может исправить мое заблуждение о том, что я делаю что-то полезное здесь.

Пример кода сервера:

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/[email protected] 
            "my.server.com",    //  kerberos principal server - myprincipal/[email protected]
            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/[email protected] 
            "my.server.com",    //  kerberos principal server - myprincipal/[email protected]
            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, когда начинал.

Спасибо за чтение.

person Wanderer    schedule 12.12.2012