Hi,
I work on applying of security policy of per-operation granularity. Some
operations of my service should be, some of them not. The non-secured
operations are used by legacy clients which don't know anything about
WS-Security; there is no way to apply any kind of security interceptor to the
clients.
My policy is (got from WS-SecurityPolicy Examples, Committee Specification 01):
<wsdl:operation name="OperationA">
<wsp:Policy wsu:Id="SecuredOperation">
<sp:SupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Always">
<wsp:Policy>
<sp:NoPassword />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>
...
</wsdl:operation>
1. Unfortunately, I cannot find way how policy-related interceptors are
added to bus.
In Spring application context, I defined (inspired by
http://cxf.apache.org/docs/wspconfiguration.html):
<import resource="classpath*:META-INF/cxf/cxf-extension-ws-security.xml" />
<import resource="classpath*:META-INF/cxf/cxf-extension-policy.xml" />
<cxf:bus>
<cxf:features>
<p:policies enabled="true"/>
<cxf:logging />
</cxf:features>
<cxf:properties>
<entry key="ws-security.callback-handler">
<ref bean="passwordCallback" />
</entry>
</cxf:properties>
</cxf:bus>
For me, this causes policy failure:
Caused by: org.apache.cxf.ws.policy.PolicyException: These policy alternatives
can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}UsernameToken
WSSecurityInterceptorProvider is being loaded, interceptors are added to, well,
something, but none of them are in interceptor chain during message handling (I
don't see them while debugging PhaceInterceptorChain). Policy framework is
initialized, but no assertions are really checked for incoming requests. (Maybe
it doesn't matter here, but framework works in OSGi environment in my case).
Did I miss something? Do you have any ideas how can I initialize/troubleshoot
security policy interceptors?
2. To workaround point 1, I added the interceptor manually:
<jaxws:endpoint ...>
<jaxws:inInterceptors>
<bean id="policyIn"
class="org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor" />
</jaxws:inInterceptors>
</jaxws:endpoint>
It works more or less ok, but there are some issues. I define policy for
operation A, but the policy is used when calculating wss4j actions for
operation B (AssertionInfoMap contains AssertionInfo with USERNAME_TOKEN while
computeAction in PolicyBasedWSS4JInInterceptor). There are no other policies in
WSDL at all, except the policy for A. After all, "UsernameToken " action is
added even if there is no token in request (and there is no policy requiring
it!). As a result, Wss4JInInterceptor fails while processing non-existent
behavior:
org.apache.cxf.binding.soap.SoapFault: An error was discovered processing the
<wsse:Security> header
The only workaround here is to send empty WS-Security header. In this case,
WSS4J interceptor doesn't fail, and policy checking does not try to apply wrong
policy.
Expected behavior, to my mind, is: don't use policy from other operation when
calculating actions, and set NoSecurity action if no policy found. Thoughts?
3. Do I understand correctly that even if service consumer uses elements
not defined in security policy, the additional elements will be simply ignored
(without any additional warning/log message), since no corresponding actions
will be passed to underlying Wss4JInInterceptor?
4. As continuation of 4, I'm a bit confused that when I set NoPassword
assertion, there is no failure even if I pass password as part of security
header:
<wsse:UsernameToken>
<wsse:Username>user</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">11</wsse:Password>
</wsse:UsernameToken>
5. Finally, I can't make references to policy working when I define the
policy in wsdl (for me, only inlined policy works ok):
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
targetNamespace="...">
<wsdl:binding ...>...
<wsdl:operation name="RetrieveGuest">
<wsp:PolicyReference URI="#SecuredOperation" />
...
</wsdl:operation>
</wsdl:binding>
<wsp:Policy wsu:Id="SecuredOperation">...
</wsp:Policy>
</wsdl:definitions>
I see exception:
Caused by: org.apache.cxf.ws.policy.PolicyException: Reference to policy
#SecuredOperation could not be resolved.
at
org.apache.cxf.ws.policy.attachment.AbstractPolicyProvider.checkResolved(AbstractPolicyProvider.java:97)
at
org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.resolveReference(Wsdl11AttachmentPolicyProvider.java:232)
at
org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getElementPolicy(Wsdl11AttachmentPolicyProvider.java:182)
Any ideas/suggestions?
Thank you in advance.
Siarhei