Wednesday, February 12, 2020

12c SOA - How to use WS Security username and Password policy for Web Services in soapUI

Why we need WS Security:
WS-Security (Web Services Security, short WSS) is a flexible and feature-rich extension to SOAP to apply security to web services.While doing Web Services/ SOA Testing, one has to make sure that the services are secured enough. Proper authorization and authorization needs to be implemented for web sercvices. Lacking of this can provide access to data and non public information of an organization to outside world.
WS Security can be implemented by creating different security policies. In this post, let us see how can we test WS Security using username and password token of a web service using soapUI.

Steps:
Double click on the test request from the test steps. Navigate to the tab "Auth" at the bottom of the request.
 Add New Authorization
 Type Basic
 Give the username, password and domain.
 Now go to the XML version of the request, right click there. Click on the tab "Add WSS Username Token. Select "Password Text" to send the password in plain text or select "Password Digest" to use an encrypted password.


You might also right click and select "Add WS-Timestamp" to add a creation/ expiration time stamp to the security header.This will create an entry like the one below under the <Security> element for the request.

Sample Request payload:
<soapenv:Envelope xmlns:emp="http://www.emp.test" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
         <wsu:Timestamp wsu:Id="TS-81CB99D5C318DB117215815012695444">
            <wsu:Created>2020-02-12T09:54:29.543Z</wsu:Created>
            <wsu:Expires>2020-02-12T09:55:29.543Z</wsu:Expires>
         </wsu:Timestamp>
         <wsse:UsernameToken wsu:Id="UsernameToken-81CB99D5C318DB117215815007891653">
            <wsse:Username>wsstest</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">wsstest12</wsse:Password>
            <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">WfBcHW3uJNb82JstzP17tg==</wsse:Nonce>
            <wsu:Created>2020-02-12T09:46:29.165Z</wsu:Created>
         </wsse:UsernameToken>
      </wsse:Security>
      <emp:requestHeader>
         <!--Optional:-->
         <emp:User>user1</emp:User>
         <!--Optional:-->
         <emp:Id>id1</emp:Id>
      </emp:requestHeader>
   </soapenv:Header>
   <soapenv:Body>
      <emp:EmployeeRequest>
         <emp:EmpId>1</emp:EmpId>
         <emp:EmpName>en</emp:EmpName>
         <emp:Address>ad</emp:Address>
      </emp:EmployeeRequest>
   </soapenv:Body>
</soapenv:Envelope>

12c SOA - WS Security - How to call a protected web-service

Now that we protected the service from unauthorized access, how do we call it from another webservice:

Implementation steps:
Open the composite.xml
Right Click on the external reference and click Configure SOA WS policies..

 Under Security click on the + button

 Scroll down and select oracle/wss_username_token_client_policy and then OK



For OSB, same option is available on the business-services.
Username and password to be passed to the service should be configured as KEYS in EM console⇾security credentials section. 

The configured key has to be entered in the csf-key property in the Reference tag in the composite.xml as highlighted below.

<property name="csf-key" type="xs:string" many="false">user-key</property>
 Instead of using CSF key, we can also provide direct user and password in the reference tag (configured in the key/User).
<property name="oracle.webservices.auth.username" type="xs:string" many="false" override="may">testKey</property>
      <property name="oracle.webservices.auth.password" type="xs:string" many="false" override="may">test1234</property>

    
If CSF key or Auth user and password are not given in the reference section of the composite.xml then it will throw the following error:
Unable to invoke endpoint URI "http://host:port/soa-infra/services/POC/DynamicEndpointURIProject/dynamicendpointuribpelprocess_client_ep" successfully due to: oracle.fabric.common.PolicyEnforcementException: WSM-00015 : The user name is missing.


12c SOA - How to create an user in Weblogic server

Go to Weblogic Console home⇾Security Realms⇾myrealm

 Click on Users and Groups tab
 Click on New button and enter username/password details.



12c SOA - WS Security- How to protect a web-service with username and password

  • A simple way of protecting web-services from unauthorized access is to use standard WS security. Web Services Security (WS-Security, WSS) is an extension to SOAP to apply security to Web services.
  • Oracle SOA suite 11g/12c provides an out of the box WS-Policies to protect web-services and to securely call a protected web service. 
Implementation:

Step1: Configure CSF Key in EM console or configure User in Weblogic server.
configure keys in Weblogic server
Click here 12c-soa-how-to-create-csf-key for the steps to create CSF-Key in em console.
create an user in Weblogic server
Click here12c-soa-how-to-create-user-in-weblogic

Step2: Configure SOA WS Policies from Jdeveloper.
Open the composite.xml
Right Click on the exposed services and click Configure SOA WS policies..
 Under Security click on the + button
Scroll down and select oracle/wss_username_token_service_policy and then OK


 Deploy

Test1: without WSSE security header
Outcome:
      <env:Fault xmlns:ns0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <faultcode>ns0:InvalidSecurity</faultcode>
         <faultstring>InvalidSecurity : error in processing the WS-Security security header</faultstring>
         <faultactor/>


      </env:Fault>

 Test2: with the WSSE Security header.
<soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>weblogic</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">welcome1<wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>

Note:
  • For OSB, the same option is available on the proxy services.
  • To test this webservice WSSE header has to be passed with username and password which were created during user/key creation.

12c SOA -BPEL - How to set the service endPoint URI dynamically using invoke endpointURI property

In BPEL 1.1, We can achieve the dynamic partnerlink using simple ws-addressing but in BPEL 2.0,We can achieve the dynamic partnerlink using EndpointReference element of ws-addressing.xsd and service-ref element of ws-bpel_serviceref.xsd.

Instead of using ws-addressing, as of 11g onwards, we can simply override the endpointURI property on runtime. It is important that the services that we want to invoke all implement the exact same wsdl as referenced in the composite reference. It will have much less clutter in the BPEL.

Use Case :
Here I will show you how to get the URI of the backend service from a repository and how to set it dynamically to our partnerLink (dynamicPartnerLink).

Implementation steps :
  1. Create two synchronous BPEL service VersionProject versions(1.0 and 2.0)
  2. Create a dvm file which stored the service endpoints.
  3. Create a BPEL component and invoke VersionProject(1.0)
  4. Add the endPointURI variable and assign the endpoint uri based on service name
  5. Set the endpointURI property in the invoke activity
Implementation:
Create a SOA Project

 Create a XSD.
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.org"
            targetNamespace="http://www.dynamiceURL.test" elementFormDefault="qualified">
    <xsd:element name="process">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="msg" type="xsd:string"/>
                <xsd:element name="ServiceName" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="processResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="result" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

 Create a Sync BPEL using the above schema.

 Create a DVM.




 Invoke the SOAP service Version Project v1.0


 Open the BPEL and create the endPointURI variable and fetch the endpoint URI using the dvm lookup function.


<assign name="AssignEndpointURIFromDVM">
<copy>
<from>dvm:lookupValue('Endpoints.dvm','ServiceName',$inputVariable.payload/ns1:ServiceName,'EndPointURI','NotFound')</from>
<to expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">$endpointURI</to>
</copy>
</assign>

Invoke the created partnerlink
 Create the Input and output variables
 Assign the endpointURI variable to endpointURI property
    <invoke name="Invoke_SOAPReference" bpelx:invokeAsDetail="no" partnerLink="SOAPReference"
            portType="ns2:VersionProcess" operation="process"
            inputVariable="Invoke_SOAPReference_process_InputVariable"
            outputVariable="Invoke_SOAPReference_process_OutputVariable">
      <bpelx:toProperties>
        <bpelx:toProperty name="endpointURI" variable="endpointURI"/>
      </bpelx:toProperties>
    </invoke>
 Assign the input to Invoke and Output


 Deploy and test.

Input: Msg: test1 and ServiceName: VersionProject1
Output: It calls the v1.0 service


Input: Msg: test2 and ServiceName: VersionProject2
Output: It calls the v2.0 service



Featured Post

11g to 12c OSB projects migration points

1. Export 11g OSB code and import in 12c Jdeveloper. Steps to import OSB project in Jdeveloper:   File⇾Import⇾Service Bus Resources⇾ Se...