Adding authorization to a third-party web service - web-services

I have several third-party web services of which I only have their WSDL's. Currently they are only accessible in my internal network. I would like to expose those web services to the internet but, since they read/write sensitive information, I would need some sort of authentication mechanism in order to assure that only certain users are able to invoke them.
The idea is to expose exactly the same interface (same operations with the same parameters) but intercepting each invocation to check the security and then invoking the original web service if the authentication is valid or returning an exception or error message otherwise. I've been trying to use Mule ESB for the task abut I can't quite get there
Is this possible with mule? If not, how would i go about doing this? Can anyone point me in the right direction?
Thanks in advance.

Here is an example of a web service proxy adding WS-Security to an unsecure target web service:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:ss="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.2/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/3.2/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/3.2/mule-spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<mule-ss:security-manager>
<mule-ss:delegate-security-provider
name="memory-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider>
<ss:user-service id="userService">
<ss:user name="user" password="pass" authorities="ROLE_USER" />
</ss:user-service>
</ss:authentication-provider>
</ss:authentication-manager>
<cxf:security-manager-callback id="serverCallback" />
</spring:beans>
<flow name="secureStockQuoteWsProxy">
<http:inbound-endpoint address="http://localhost:8080/sec-ws/stockquote"
exchange-pattern="request-response">
<cxf:proxy-service>
<cxf:inInterceptors>
<spring:bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<spring:bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<spring:constructor-arg>
<spring:map>
<spring:entry key="action" value="UsernameToken" />
<spring:entry key="passwordCallbackRef"
value-ref="serverCallback" />
</spring:map>
</spring:constructor-arg>
</spring:bean>
</cxf:inInterceptors>
</cxf:proxy-service>
</http:inbound-endpoint>
<http:outbound-endpoint address="http://www.webservicex.net/stockquote.asmx"
exchange-pattern="request-response">
<cxf:proxy-client enableMuleSoapHeaders="false"
soapVersion="1.2" />
</http:outbound-endpoint>
</flow>

http://www.webservicex.net/stockquote.asmx?wsdl gives the same result. So you could test it there. Maybe the problem lies with .net services.
Anyway, for now I made a successful proxy with the webservice pattern. Now I am still working on transforming a response. Not with much success because Mule keeps giving me a ReleasingInputStream as response.

Related

Missing SOAPAction header when invoking WS with Camel-CXF

We are trying to a invoke Soap service using Camel-Cxf/Fuse and using Payload dataformat. Some times client is rejecting request saying SOAPAction is missing and this is intermittent. Is there a way for us to set SOAPAction specifically during service invocation? In what cases we fail to send SOAPAction? Here is the configuration we are using for invocation.
<!-- CXF configuration pointing to WSDL URL and service Name -->
<cxf:cxfEndpoint id="abcSOAPCPOutbound"
wsdlURL="wsdl/FooService.wsdl"
endpointName="cNS:FooServiceSoap"
serviceName="cNS:FooService"
address="http://example.com/processRequest.asmx"
xmlns:cNS="http://www.example.com"
loggingFeatureEnabled="false">
<cxf:inInterceptors>
<ref bean="GZIPInInterceptor"/>
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="iuABCSOAPOutboundInterceptor"/>
</cxf:outInterceptors>
</cxf:cxfEndpoint>
<!-- Came route for invoking service with operationName header set -->
<route id="iuFooOutboundRoute">
<from uri="direct-vm:iuOutboundtoFoo"/>
<setHeader headerName="operationName" >
<constant>FooSync</constant>
</setHeader>
<convertBodyTo type="String"/>
<!-- Send to Colibrium -->
<to uri="cxf:bean:abcSOAPCPOutbound?dataFormat=PAYLOAD"/>
<process ref="extractHTTPStatusCode"/>
</route>
Does it cause any problem if we set camel header as SOAPAction before invoking service?
Yes,
The same way as you do operationName:
<setHeader headerName="SOAPAction">
<constant>DummyOperation</constant>
</setHeader>
You can refer here - http://www.javaworld.com/article/2078883/open-source-tools/java-tip-write-an-soa-integration-layer-with-apache-camel.html?page=4

Mule invoking database connector from cxf soap service to call multple stored procedure in each method

Can you please help me and provide any example or scenario in which I can invoke db call using flow from web service operation. if my web service implementation have five operations and each operation has to call a separate query or stored procedure.
I have the other way around by injecting database template using spring injection and call the required query or stored procedure but I want to do it with flows.
Take a look at CXF proxy service:https://docs.mulesoft.com/mule-user-guide/v/3.7/proxying-web-services-with-cxf
It allows to access the raw SOAP message and route it how you wish, such as using a choice router using Xpath on the operation name, or you could extract the SOAPAction header etc.
<flow name="soap-api" doc:name="soap-api-orders">
<https:.... />
<cxf:proxy-service payload="body"
service="MyService-v1c" namespace="http://xmlns.oracle.com/MyService"
wsdlLocation="wsdl/MyService.wsdl" enableMuleSoapHeaders="false"
doc:name="CXF" />
<choice doc:name="Choice">
<when
expression="#[xpath('boolean(//mynamespace:MyOperation1/node()[1])')]">
<flow-ref name="flow1" />
</when>
<when
expression="#[xpath('boolean(//mynamespace:MyOperation2/node()[1])')]">
<flow-ref name="flow2" />
</when>
<otherwise>
</otherwise>
</choice>
</flow>

WCF 4 routing service throws handler error

I am trying to use WCF 4 routing declaratively to redirect one branch of my (REST) web services to an alternate server. I configured WCF's System.ServiceModel.Routing.RoutingService to route http://oldserver:81/FileService/ calls to http://newserver:82/FileService/, but when I try to access the redirected service, all it does is throw the error
Handler "HttpLogging" has a bad module "HttpLoggingModule" in its module list
I can enter URLs to the new service in my browser and they work fine, but URLs to the old service (to be re-routed) fail.
I have added the following routing configuration into my web service application:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="routingConfig">
<!-- Specify the routing table to use. -->
<routing filterTableName="routingTable1" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<!-- WCF routing table -->
<routing>
<filters>
<filter name="FileFilter1" filterType="EndpointName" filterData="FileService"/>
</filters>
<filterTables>
<filterTable name="routingTable1">
<add filterName="FileFilter1" endpointName="FileService" />
</filterTable>
</filterTables>
</routing>
<client>
<!-- Destination endpoint defining the base URL where File messages will be routed. -->
<endpoint name="FileService"
address="http://newserver:82/FileService/"
binding="webHttpBinding"
contract="*" />
</client>
<services>
<!-- WCF routing service. -->
<service name="System.ServiceModel.Routing.RoutingService" behaviorConfiguration="routingConfig" >
<host>
<baseAddresses>
<!-- The service endpoint to be redirected. -->
<add baseAddress="http://oldserver:81/FileService" />
</baseAddresses>
</host>
<!-- Define the endpoints of the service to receive messages. -->
<endpoint name="reqReplyEndpoint" binding="webHttpBinding" contract="System.ServiceModel.Routing.IRequestReplyRouter" address="" />
</service>
</services>
There is no longer a FileService service in the application, except the one that should be exposed by the routing service.
I've tried:
filter types of MatchAll, EndpointAddress, and PrefixEndpointAddress;
various forms of the old service addresses;
different names for filters, routing tables, services;
renaming contracts.
None of it gets my client to call the redirected service, much less even any indication that the routing service is operational or even configured at all.
How do I make the routing actually work? Failing that, how would I debug it so I can determine what to fix?
The general problem I see is that you are trying to route REST calls with Routing Service, which is not supported. MSDN reference:
https://msdn.microsoft.com/en-us/library/ee517423.aspx
The Routing Service does not currently support routing of WCF REST
services. To route REST calls, consider using System.Web.Routing or
Application Request Routing
(http://go.microsoft.com/fwlink/?LinkId=164589).
Blockquote

copy complexType to message in BPEL

I am using Apache ODE to write some simple BPEL's to connect 2 web services.
One of the WSDL files of my two services contains this complex type:
<types>
<t:schema targetNamespace="http://ws.panos.com/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<t:complexType name="myObject">
<t:sequence>
<t:element minOccurs="0" name="str" type="t:string" />
</t:sequence>
</t:complexType>
</t:schema>
How do I make a copy from a service return message (which is just a xsd:string) to the input of a message (inside "str" of type "myObject"?
I have tried to do this, but doesnt seem to work:
<assign name="assign_2">
<copy>
<from variable="wsA_output" part="return"/>
<to variable="wsC_input" part="arg0" query="/arg0/str"/>
</copy>
I always get a null string transfered. Help much appreciated.
The to-spec <to variable="..." part="..." query="..."/> is not valid in BPEL 1.1 nor BPEL 2.0. The correct equivalent expression is: <to>$wsC_input.arg0/arg0/str</to> or <to variable="wsC_input" part="arg0"><query>/arg0/str</query></to>. Please make also sure that you initialize the variable before assigning values to nested structures.
Just found the mistake. You are right, we need to query in order to find the field like this:
<assign name="assign_2">
<copy>
<from variable="wsA_output" part="return"/>
<to>$wsC_input.message/arg0/str</to>
</copy>
</assign>
Also, we need to initialize the variable like this:
<assign name="assign_init">
<copy>
<from>
<literal><arg0><str xmlns="">nothing</str></arg0></literal>
</from>
<to variable="wsC_input" part="arg0"></to>
</copy>
</assign>
The xmlns="" is needed when the default namespace in your bpel is different that the namespace in the receiving web service.
I am just writing these down for future reference :)
Again, thanks for you your answer.
Some links that could also help other people:
http://ode.apache.org/faq.html
http://jee-bpel-soa.blogspot.com/2009/08/manipulating-ws-bpel-variables-and.html

Download specific version of a file from SharePoint using web services

Can someone provide a sample for downloading a specific version of a file from SharePoint using web services? Normally I would get the file with the Copy Web Service (.../_vti_bin/copy.asmx). But I don't really know how to specify a version.
Regards
Anton Kalcik
You can use the Versions web service to get which versions exist for a File
The GetVersions method will give you an xml like this:
<results xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<list id="{26E516B0-8241-4B97-984D-000000000000}" />
<versioning enabled="1" />
<settings url="http://Server_Name/Site_Name/_layouts/
1033/LstSetng.aspx?
List={26E516B0-8241-4B97-984D-000000000000}" />
<result version="#4" url="http://Server_Name/Site_Name/
Shared Documents/File_Name.doc"
created="6/7/2003 5:55 PM" createdBy="DOMAIN\User" size="19968"
comments="" />
<result version="1" url="http://Server_Name/Site_Name/
_vti_history/1/Shared Documents/File_Name.doc"
created="6/7/2003 5:49 PM" createdBy="DOMAIN\User" size="19968"
comments="" />
.
.
.
</results>
You can then just use a HTTP GET request for the content of the "url" attribute of the "result" node for the right version
Here's the exact thing you want to do, with code:
Article