Friday, June 27, 2014

Securing OSB SOAP service with WS-Policy UsernameToken

Since we had some issue with OWSM and Attachments (solved in 11.1.1.7, but we are on 11.1.1.5) we decided to use some Predefined Web Service Security Policy.

The proxy has this WSDL :

<wsdl:definitions name="PVHelloWorld" 
targetNamespace="http://www.example.org/PVHelloWorld/" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/PVHelloWorld/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

  <wsdl:types>
 <xsd:schema>
  <xsd:import namespace="http://www.example.org/PVHelloWorld/" schemaLocation="PVHelloWorld.xsd"/>
 </xsd:schema>
  </wsdl:types>
  
  <wsdl:message name="HelloWorldRequest">
    <wsdl:part element="tns:HelloWorldRequest" name="parameters"/>
  </wsdl:message>
  
  <wsdl:message name="HelloWorldResponse">
    <wsdl:part element="tns:HelloWorldResponse" name="parameters"/>
  </wsdl:message>
  
  <wsdl:portType name="PVHelloWorldPortType">
    <wsdl:operation name="HelloWorld">

      <wsdl:input message="tns:HelloWorldRequest">

</wsdl:input>
      <wsdl:output message="tns:HelloWorldResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  
  <wsdl:binding name="PVHelloWorldPortBinding" type="tns:PVHelloWorldPortType">

    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="HelloWorld">
      <soap:operation soapAction="http://www.example.org/PVHelloWorld/HelloWorld"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  
  <wsdl:service name="PVHelloWorld">
    <wsdl:port binding="tns:PVHelloWorldPortBinding" name="PVHelloWorldPort">
      <soap:address location="http://www.example.org/"/>
    </wsdl:port>
  </wsdl:service>
  
</wsdl:definitions>



where the PVHelloWorld.xsd is:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
 targetNamespace="http://www.example.org/PVHelloWorld/" 
 xmlns:tns="http://www.example.org/PVHelloWorld/" 
 elementFormDefault="qualified">

    <element name="HelloWorldRequest" type="string"></element>

    <element name="HelloWorldResponse" type="string"></element>
    
</schema>


After you have to apply security to Request only.


If you apply Security to Operation, then it tries to apply security also to Response, and it fails:
####<Jun 27, 2014 10:23:40 AM CEST> <Error> <OSB Security> <acme102> <osbdev1ms1> <[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <7f9b72b69446518a:670088d3:146d8a74ad2:-8000-0000000000004f16> <1403857420200> <BEA-387023> <An error ocurred during web service security inbound response processing [error-code: Fault, message-id: 6720812917736772435-670088d3.146d8a74ad2.-7882, proxy: PVSecurityTest/PVHelloWorld, operation: HelloWorld]
--- Error message:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Header/><env:Body><env:Fault><faultcode>env:Server</faultcode><faultstring>Unable to add security token for identity</faultstring></env:Fault></env:Body></env:Envelope>
weblogic.xml.crypto.wss.WSSecurityException: Unable to add security token for identity
        at weblogic.wsee.security.wss.SecurityPolicyDriver.doIdentity(SecurityPolicyDriver.java:193)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processIdentity(SecurityPolicyDriver.java:162)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processOutbound(SecurityPolicyDriver.java:74)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processOutbound(SecurityPolicyDriver.java:65)
        at weblogic.wsee.security.WssServerHandler.processOutbound(WssServerHandler.java:88)
        at weblogic.wsee.security.WssServerHandler.processResponse(WssServerHandler.java:70)
        at weblogic.wsee.security.WssHandler.handleResponse(WssHandler.java:127)
        at com.bea.wli.sb.security.wss.wls.Wls92InboundHandler.processResponse(Wls92InboundHandler.java:261)
        at com.bea.wli.sb.security.wss.WssHandlerImpl.doInboundResponse(WssHandlerImpl.java:918)
        at com.bea.wli.sb.context.BindingLayerImpl.createTransportReplySender(BindingLayerImpl.java:416)
        at com.bea.wli.sb.context.BindingLayerImpl.addResponse(BindingLayerImpl.java:506)
        at com.bea.wli.sb.pipeline.MessageProcessor.finishProcessing(MessageProcessor.java:349)
        at com.bea.wli.sb.pipeline.RouterCallback.onReceiveResponse(RouterCallback.java:108)
        at com.bea.wli.sb.pipeline.RouterCallback.run(RouterCallback.java:183)
        at weblogic.work.ContextWrap.run(ContextWrap.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
>




You must then customize the policy (by default, everyone can access):




and add the condition User = BLA (it's covered in red in the picture below)




The alternative is to embed policies in the WSDL:

This to be put only once:

<wsp:UsingPolicy wsdl:Required="true" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>

and this to be applied for each part you want to protect with Authorization:

<wsp:Policy> <wsp:PolicyReference URI="policy:Auth.xml"/> </wsp:Policy>

The curious thing is that if Request authentication fails, the service error handler is invoked:


 <con:fault xmlns:con="http://www.bea.com/wli/sb/context">
  <con:errorCode>BEA-386201</con:errorCode>
  <con:reason>A web service security fault occurred[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}FailedAuthentication][Failed to assert identity with UsernameToken.]</con:reason>
  <con:details>
    <err:WebServiceSecurityFault xmlns:err="http://www.bea.com/wli/sb/errors">
      <err:faultcode xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">oas:FailedAuthentication</err:faultcode>
      <err:faultstring>Failed to assert identity with UsernameToken.</err:faultstring>
    </err:WebServiceSecurityFault>
  </con:details>
  <con:location>
    <con:path>request-pipeline</con:path>
  </con:location>
</con:fault>






No comments: