This article builds on part I by showing how to use the secret key associated with a Kerberos Token to secure (sign and encrypt) the request. This functionality was added as part of WSS4J 1.6.3, and the related WS-SecurityPolicy functionality was released as part of CXF 2.4.3.
1) Setting up the Kerberos system tests in Apache CXF
If you have not done so already, follow the instructions in part I to install a Kerberos distribution and to generate client and service principals to run the CXF Kerberos system tests. The KerberosTokenTest in Apache CXF contains a number of different Kerberos tests. In this article we will examine the tests that involve obtaining a Kerberos Token, and using the associated secret key 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"
1.1) Installing a custom KerberosTokenDecoder
Once the client obtains an AP-REQ token from the KDC, the client also has easy access to the session key, which can be used to secure the request in some way. Unfortunately, there appears to be no easy way to obtain the session key on the receiving side. WSS4J does not support extracting a Kerberos session key on the receiving side to decrypt/verify a secured request out-of-the-box. Instead, a KerberosTokenDecoder interface is provided, which defines methods for setting the AP-REQ token and current Subject, and a method to then get a session key. An implementation must be set on the KerberosTokenValidator to obtain a session key to decrypt or verify a signed request.
To run the Kerberos system tests that require a secret key on the receiving side, download an implementation of the KerberosTokenValidator interface here, and copy it to "systests/ws-security/src/test/java/org/apache/cxf/systest/ws/kerberos/server". The implementation is based on code written by the Java Monkey, and uses internal sun APIs, and so can't be shipped in Apache CXF/WSS4J. Once this implementation has been copied into the ws-security module, then you must compile or run any tests with the "-Pnochecks" profile enabled, as otherwise the code fails checkstyle.
Open the server configuration file ("src/test/resources/org/apache/cxf/systest/ws/kerberos/server/server.xml"), and uncomment the "kerberosTicketDecoderImpl" bean, and the property of the "kerberosValidator" bean that refers to it:
<bean id="kerberosTicketDecoderImpl" class="org.apache.cxf.systest.ws.kerberos.server.KerberosTokenDecoderImpl"/>1.2) Running the tests
<bean id="kerberosValidator"
class="org.apache.ws.security.validate.KerberosTokenValidator">
<property name="contextName" value="bob"/>
<property name="serviceName" value="bob@service.ws.apache.org"/>
<property name="kerberosTokenDecoder" ref="kerberosTicketDecoderImpl"/>
</bean>
Open KerberosTokenTest.java and comment out the "@org.junit.Ignore" entries for the last four tests, "testKerberosOverTransportEndorsing", "testKerberosOverAsymmetricEndorsing", "testKerberosOverSymmetricProtection" and "testKerberosOverSymmetricDerivedProtection". Finally, run the tests via:
mvn -Pnochecks test -Dtest=KerberosTokenTest -Djava.security.auth.login.config=src/test/resources/kerberos.jaas2) The tests in more detail
In this section, we'll look at the tests in more detail.
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:
- testKerberosOverTransportEndorsing: A (one-way) transport binding is defined, with a KerberosToken required as an EndorsingSupportingToken.
- testKerberosOverAsymmetricEndorsing: An asymmetric binding is used, where a KerberosToken is required as an EndorsingSupportingToken.
- testKerberosOverSymmetricProtection: A symmetric binding is used, where a KerberosToken is specified as a ProtectionToken of the binding.
- testKerberosOverSymmetricDerivedProtection: The same as the previous test-case, except that any secret keys that are used must be derived.
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 a KerberosTokenValidator instance given above. It requires a "contextName" property, which corresponds to the JAAS context name, as well as an optional "serviceName" property, and an optional "kerberosTokenDecoder" property to use to obtain a secret key. Combined with the JAAS properties file, this is all that is required for the service endpoint to validate a received Kerberos Token.
<jaxws:properties>
<entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
</jaxws:properties>
</jaxws:endpoint>
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, I wonder if you can help me. I have to do a web service that shows this kind of structure during WS consumption:
ReplyDeletesoapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsk="...
soapenv:Body>
<ws:
I put just the part I need to fit.
I've checked on internet and it look like this have sort of kerberos integration, but I can't reach it.
I don't know how to change the definition from ws to wsk
ReplyDelete
ReplyDeleteFeel free to ask on the CXF user list: http://cxf.apache.org/mailing-lists.html
Colm.
hello
ReplyDeleteplease you write
The client configuration is available (here) but the link isn't working .. can you reupload it if available
Ok I updated the link. Bear in mind that this article is quite old now, and it links to the old SVN repo. Newer CXF releases uses "git" instead, the SVN repo in question is not actively maintained anymore.
Delete