You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Dan Kimmel <dk...@rjssoftware.com> on 2012/11/08 01:34:09 UTC

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="bob@service.ws.apache.org" />
</bean>
</entry>
</jaxws:properties>
</jaxws:client>



Re: Either/Or KerberosToken/UsernameToken

Posted by Daniel Kulp <dk...@apache.org>.
On Nov 8, 2012, at 7:19 AM, Andrei Shakirin <as...@talend.com> wrote:

> As a third way, you can define own alternativeSelector that implements org.apache.cxf.ws.policy.selector.AlternativeSelector interface and select KerberosToken or UsernameToken alternative depends on external conditions. By default PolicyEngine uses MinimalAlternativeSelector.

That's likely the best solution.

A forth option would be to grab the bus and do something like:

PolicyInterceptorProviderRegistry reg = bus.getExtension(PolicyInterceptorProviderRegistry.class);
reg.get(SP12Constants.KERBEROS_TOKEN);
reg.remove(SP12Constants.KERBEROS_TOKEN);

The "get" there would trigger a loading of all the interceptor providers.   Then remove the provider for Kerberos if kerberos isn't usable.   The AlternaiveSelector would then not be able to use the policy with the kerberos.


Dan




> 
> Here is short description how to configure it: http://cxf.apache.org/docs/wspconfiguration.html.
> 
> Cheers,
> Andrei.
> 
> -----Original Message-----
> From: Andrei Shakirin [mailto:ashakirin@talend.com] 
> Sent: Donnerstag, 8. November 2012 12:10
> To: users@cxf.apache.org
> Cc: dkimmel@rjssoftware.com; Colm O hEigeartaigh
> Subject: RE: Either/Or KerberosToken/UsernameToken
> 
> 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:dkimmel@rjssoftware.com] 
> Sent: Donnerstag, 8. November 2012 01:34
> To: users@cxf.apache.org
> 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="bob@service.ws.apache.org" /> </bean> </entry> </jaxws:properties> </jaxws:client>
> 
> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


RE: Either/Or KerberosToken/UsernameToken

Posted by Andrei Shakirin <as...@talend.com>.
As a third way, you can define own alternativeSelector that implements org.apache.cxf.ws.policy.selector.AlternativeSelector interface and select KerberosToken or UsernameToken alternative depends on external conditions. By default PolicyEngine uses MinimalAlternativeSelector.

Here is short description how to configure it: http://cxf.apache.org/docs/wspconfiguration.html.

Cheers,
Andrei.

-----Original Message-----
From: Andrei Shakirin [mailto:ashakirin@talend.com] 
Sent: Donnerstag, 8. November 2012 12:10
To: users@cxf.apache.org
Cc: dkimmel@rjssoftware.com; Colm O hEigeartaigh
Subject: RE: Either/Or KerberosToken/UsernameToken

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:dkimmel@rjssoftware.com] 
Sent: Donnerstag, 8. November 2012 01:34
To: users@cxf.apache.org
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="bob@service.ws.apache.org" /> </bean> </entry> </jaxws:properties> </jaxws:client>



RE: Either/Or KerberosToken/UsernameToken

Posted by Andrei Shakirin <as...@talend.com>.
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:dkimmel@rjssoftware.com] 
Sent: Donnerstag, 8. November 2012 01:34
To: users@cxf.apache.org
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="bob@service.ws.apache.org" /> </bean> </entry> </jaxws:properties> </jaxws:client>