I am using the Java class org.apache.hadoop.security. authentication.server.AuthenticationFilter from Apache Hadoop 2.5.0 as a filter in front of a Tomcat 6 Servlet we wish to add Kerberos authentication to.
I am attempting to write some test cases against this filter so that we have a better understanding of how it works and what it does.
In order for the filter to authenticate a user, it is reading the 'Authorization' header of the HTTP request, expecting the value to contain 'Negotiate '
My understanding of how Kerberos works leads me to believe that I should be able to write code while creating my HTTP request that looks something like this:
// normally the server principal keytab is not available from the client side,
// but for the purpose of making test cases I see no problem with sharing the keytab
// between the client side and the server side
javax.security.auth.kerberos.Keytab kt = KeyTab.getInstance("keytab");
KerberosKey keys[] = kt.getKeys("HTTP/[email protected]");
SomeTokenType token = new SomeTokenType();
<code to set token parameters>
// my understanding of Kerberos is that the only cyphertext key
// needed on this token
// is one of the server principal's keys from the Keytab file
// (which does contain ~5
// keys of different sizes and types, I've checked)
EncryptedTokenType etoken = <encrypt token with a key from keys>
byte[] array = etoken.getBytes();
httprequest.addHeader("Authorization","Negotiate " + new Base64(0).encode(array));
So, questions here:
- What is the Java Class that embodies the Kerberos Auth Token sent in "Authorization Negotiate"?
- What fields of that auth token have to be set to what values?
- What is the encryption algorithm used to encrypt the auth token against the keytab key?
- What is the best keytab key to use?
- What is the mechanism for byte-serializing the auth token, once encrypted?
You are correct in that it is possible to "forge" a ticket in this manner. However, I know of no standard kerberos API that would do this.
You'll essentially need to reverse engineer the entire kerberos protocol to create a service ticket based on the keytab. The service ticket format is documented here
https://www.ietf.org/rfc/rfc4120.txt
You can use any of the keys in the keytab to encyrpt the service ticket. Once you have the service ticket, you'll need to implement this RFC to create the negotiation header.
https://www.rfc-editor.org/rfc/rfc4559
Generally, it's a lot simpler to just get a keytab for a client principal and use that and kinit to get a service ticket for testing. Your approach could work and there is probably hacker code out there somewhere to implement it, but it's an extremely non-standard way to do testing in a kerberos environment.