Actually I see two possible ways to do it:

1. Try to set wsp:Optional="true" for both policy assertions: sp:KerberosToken 
and sp:UsernameToken. KerberosTokenOut(In) interceptors will still try to get a 
token and if it will be null, just not call setAsserted(true) for assertion. As 
far as assertion is optional, it is not an error. The same way it should work 
with UsernameToken.
It MAY works, but drawbacks of this way are that code still try to obtain 
tokens and there is no control if both kind of token are missing in the message.

2. More complex way is to write own interceptor and put it before 
PolicyInInterceptor/PolicyOutInterceptor. The custom interceptor will check if 
Kerberos or UsernameToken should be used; prepare policy with appropriate 
assertion; compile policy with Neethy engine and set Policy object into 
PolicyConstants.POLICY_OVERRIDE message property. CXF will automatically use 
prepared policy. I can provide a sample code that illustrate this approach.

Perhaps Colm can recommend other more elegant way to do it.

Cheers,
Andrei.

-----Original Message-----
From: Dan Kimmel [mailto:[email protected]] 
Sent: Donnerstag, 8. November 2012 01:34
To: [email protected]
Subject: RE: Either/Or KerberosToken/UsernameToken

I have a web application that accesses my CXF 2.7 webservice. The client web 
application is configured as a CXF client. Most of the time, both applications 
(the client and the server) run independently in the same Tomcat instance.

I want the WS-Security between the two to be either Kerberos or UsernameToken. 
Kerberos if operating in an environment with a domain server, UsernameToken 
otherwise. If in a domain server setup, Tomcat and the web application (server) 
will gather user identity from the browser environment. If not, the client puts 
up a login panel and stores username and password in a session cookie.

The policy was pretty easy once I worked it out. It sets up the server side 
just fine. I can configure the client webapp easily as either Kerberos or 
UsernameToken, but I can't figure out how to switch them. I put the Kerberos 
first in the policy list. What I'd like is to be able to "non-support" Kerberos 
on those instances where there is no domain server and have CXF client policy 
engine revert to UsernameToken. Suggestions? I'd like it to be easy for my 
users to set up.

Seems like the simplest would be to have a ws-security.supports.Kerberos 
boolean property to set for PolicyEngine.supportsAlternative() to check. 
Instead, PolicyInterceptorProviderRegistryImpl seems to just dump in all the 
policies CXF supports with no regard for what I want it to support.

How do I configure CXF client to support only Kerberos OR UsernameToken?

Here's my policy:
<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702";
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy";>
<wsp:ExactlyOne >
<wsp:Policy>
<sp:KerberosToken 
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient";>
<wsp:Policy >
<sp:WssKerberosV5ApReqToken11/>
</wsp:Policy>
</sp:KerberosToken>
</wsp:Policy>
<wsp:Policy>
<sp:UsernameToken 
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient";>
<wsp:Policy >
<sp:WssUsernameToken11/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</wsp:ExactlyOne>
</wsp:Policy>

Here's the client cxf.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:jaxws="http://cxf.apache.org/jaxws";
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd";>
<import resource="classpath:META-INF/cxf/cxf.xml" />

<jaxws:client
name="{http://webservice.workflow.rjssoft.com/}WorkflowWebservice";
createdFromAPI="true">
<!-- the constructor argument MAY be included to set up which authentication 
mechanism to use the policy on the service-side is set up to accept either 
UsernameToken or KerberosToken <jaxws:outInterceptors> tests show the 
WSS4JOutInterceptor does more than we want it to do and does it differently 
using a different location for username and password than the jaxws 
policy-based stuff does <bean 
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" /> <entry key="passwordType" 
value="PasswordText" /> </map> </constructor-arg> </bean> 
</jaxws:outInterceptors>
-->
<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="[email protected]" /> </bean> </entry> </jaxws:properties> 
</jaxws:client>


Reply via email to