Siarhei Kaneuski
2010-02-05 17:35:25 UTC
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
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