In this post we will talk about installing the MIT Kerberos distribution in Ubuntu, and creating the necessary credentials to run some tests. Then we will go into some system tests in CXF that show how a client can get a Kerberos AP-REQ ticket from a KDC and send it to a service provider, who then authenticates the ticket, all driven by some spring configuration and WS-SecurityPolicy.
1) Installing MIT Kerberos
1.1) Installing the product
In this section we cover how to install the MIT Kerberos distribution in Ubuntu. This is needed to run the CXF Kerberos system tests. See here for more information on using Kerberos on Ubuntu. Open a command prompt and type:
sudo apt-get install krb5-kdc krb5-admin-serverWhen the product is installing you'll be asked for the default Kerberos Version 5 realm. Enter:
WS.APACHE.ORGYou will then be prompted for the hostnames of Kerberos servers in the WS.APACHE.ORG Kerberos realm. As we are installing the KDC and running the tests on the same machine, we only need to enter "localhost". Similarly, enter "localhost" when prompted for the Administrative server for the Kerberos realm.
1.2) Modifying configuration
Once apt-get has finished, we need to modify the Kerberos configuration file ("sudo vi /etc/krb5.conf"):
- Under the "[realms]" section, add a "default_domain" entry for ws.apache.org. The entire entry should look like:
WS.APACHE.ORG = {
kdc = localhost
admin_server = localhost
default_domain = ws.apache.org
} - Under the "[domain_realm]" section, add the following:
ws.apache.org = WS.APACHE.ORG
.ws.apache.org = WS.APACHE.ORG
- Finally, add a logging section:
1.3) Create principals[logging]
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmin.log
default = FILE:/var/log/krb5lib.log
The next step is to create some principals. Create a master key via:
sudo kdb5_util create -sThe next step is to start kadmin locally via:
sudo kadmin.localIf you run "listprincs" at the prompt you should see the ticket-granting-ticket principal "krbtgt/WS.APACHE.ORG@WS.APACHE.ORG". We will add a client principal and service principal:
addprinc alice"quit" the kadmin prompt, and start the KDC with "sudo krb5kdc". If you see no error messages then everything should be working correctly. To test this try to get a ticket for "alice" via "kinit alice", entering the password given when creating the "alice" principal.
addprinc bob/service.ws.apache.org
1.4) Create keytabs
To avoid having to enter passwords when running the tests, we will create Keytabs. Start kadmin.local again ("sudo kadmin.local"), and enter:
ktadd -k /etc/alice.keytab aliceTo check that the keytabs were create correctly, you can inspect them with klist, e.g. "sudo klist -k /etc/alice.keytab". Finally make sure the keytabs are readable via "sudo chmod og+r /etc/*.keytab" - obviously this is not secure, but it is sufficient for this test application.
ktadd -k /etc/bob.keytab bob/service.ws.apache.org
2) Running the Kerberos system tests in Apache CXF
Now that we have installed Kerberos and created the relevant principals, we can run the Kerberos system tests in Apache CXF. These tests are @Ignore'd by default. The KerberosTokenTest contains a number of different Kerberos tests. In this article we will just examine the tests that involve obtaining a Kerberos Token, and not any of the tests that involve using the secret key associated with a Kerberos Token to secure some part of the request.
Firstly, make sure that the JDK has unlimited security policies installed, and then checkout the CXF trunk via:
svn co https://svn.apache.org/repos/asf/cxf/trunk/Go into the "trunk" directory, and compile and install CXF via "mvn -Pfastinstall" (this will avoid running tests). Finally go into the WS-Security system tests in "systests/ws-security". Open KerberosTokenTest.java and comment out the "@org.junit.Ignore" entries for the first four tests, "testKerberosOverTransport", "testKerberosOverSymmetric", "testKerberosOverSymmetricSupporting" and "testKerberosOverAsymmetric". Finally, run the tests via:
mvn test -Dtest=KerberosTokenTest -Djava.security.auth.login.config=src/test/resources/kerberos.jaas
2.1) WS-SecurityPolicy configuration
The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the four tests defined above:
- testKerberosOverTransport: A (one-way) transport binding is defined, with a KerberosToken required as a SupportingToken. Essentially, this means that the communication is secured with TLS, and authentication is handled by a Kerberos token.
- testKerberosOverSymmetric: A symmetric binding is used, where a KerberosToken is required as a SignedSupportingToken.
- testKerberosOverSymmetricSupporting: A symmetric binding is used, where a KerberosToken is required as a SupportingToken.
- testKerberosOverAsymmetric: An asymmetric binding is used, where a Kerberos token is required as a SignedSupportingToken.
<sp:KerberosToken sp:IncludeToken=".../Once">This means that a GSS V5 AP-REQ Token is required "once", in other words the initial invocation between the client and service endpoint must contain a token of this type encoded as a BinarySecurityToken in the security header of the request.
<wsp:Policy>
<sp:WssGssKerberosV5ApReqToken11/>
</wsp:Policy>
</sp:KerberosToken>
2.2) Kerberos LoginModule configuration
Both the CXF client and service endpoint use JAAS to authenticate to the KDC. The JAAS file used as part of the system test is passed to the tests via the System property "java.security.auth.login.config". The client (alice) uses the following login module:
alice {and the service endpoint (bob) uses:
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"
principal="alice";
};
bob {2.3) Service endpoint configuration
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true useKeyTab=true storeKey=true
keyTab="/etc/bob.keytab" principal="bob/service.ws.apache.org";
};
The service endpoints are spring-loaded. Each endpoint definition contains the JAX-WS property "ws-security.bst.validator" which is defined in SecurityConstants. WSS4J uses Validator implementations to perform validation on received security tokens. This particular property means that BinarySecurityTokens are to be validated by the given reference, e.g.:
<jaxws:endpoint ...>"kerberosValidator" is defined as:
<jaxws:properties>
<entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
</jaxws:properties>
</jaxws:endpoint>
<bean id="kerberosValidator"The KerberosTokenValidator class ships with Apache WSS4J. It requires a "contextName" property, which corresponds to the JAAS context name, as well as an optional "serviceName" property. Combined with the JAAS properties file, this is all that is required for the service endpoint to validate a received Kerberos Token.
class="org.apache.ws.security.validate.KerberosTokenValidator">
<property name="contextName" value="bob"/>
<property name="serviceName" value="bob@service.ws.apache.org"/>
</bean>
2.4 Client configuration
Finally, the client must contact a KDC and obtain a Kerberos Token, once it sees that the service endpoint has a security policy that requires a KerberosToken. The client configuration is available here. A sample configuration for the Kerberos Test case is as follows:
<jaxws:client name="{...}DoubleItKerberosTransportPort"The JAX-WS property "ws-security.kerberos.client" (again, defined in SecurityConstants) corresponds to a KerberosClient object. Similar to the KerberosTokenValidator on the receiving side, this is configured with a JAAS context Name and service Name.
createdFromAPI="true">
<jaxws:properties>
<entry key="ws-security.kerberos.client">
<bean class="org.apache.cxf.ws.security.kerberos.KerberosClient">
<constructor-arg ref="cxf"/>
<property name="contextName" value="alice"/>
<property name="serviceName" value="bob@service.ws.apache.org"/>
</bean>
</entry>
</jaxws:properties>
</jaxws:client>
Hi Colm,
ReplyDeleteif I check out only: https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/
I can not run the test, because maven does not find his parent pom.
Non-resolvable parent POM: Could not find artifact org.apache.cxf:cxf-parent:pom:2.5.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 21, column 13
Do I need to checkout the whole trunk, or is there a better solution?
Hi Jan,
ReplyDeleteYou're right. The best way is to checkout the trunk and do a "mvn -Pfastinstall" before running the system tests. I'll update the blog entry.
Thanks,
Colm.
Hello,
ReplyDeletethanks a lot for this tutorial. do you have an example project? I already have a running KDC, but my server and client does not work.
thanks
ludi
Hi Ludi,
ReplyDeleteYes, look at section "2" - "Running the Kerberos system tests in Apache CXF ". It goes through some Kerberos tests in Apache CXF, where a client contacts a KDC (set up in section "1") to get a ticket and send it to a service provider using WS-Security.
Colm.
I have a cxf webservice client deploy on JBoss 7.1 . The client need to do kerberos authentication with the remote web service (use a keytab file).My application and the remote web service share the same Active directory (diffrents host in the same company).
ReplyDeleteWhat changes I have to do in the Jboss configuration in order to support this authentication ?
I don't work with JBoss, so I don't know. Perhaps ask on the JBoss users list.
ReplyDeleteColm.
Accuratesolutionsltd ! ein Web-Design Firma . Wir bauen Entwürfe auf dem neuesten Stand der Technik . Web-Design Berlin, Deutschland . wir sprechen einfach Englisch, liefern pünktlich und lieben es, unsere Kunden zufrieden.
ReplyDelete