How can I put an XML mocked payload into a POST request payload sended by a WSO2 ESB send mediator? - middleware

I am absolutly new in WSO2 ESB and at this time I have to achive this first simple task but I really don't know from where start.
I have to perform an HTTP POST request towards an external web service. This request should contains a mocked XML document as payload (at this time the XML have to be merely mocked so I think that I have to "write" it somewhere or something like this).
So starting by this minimalistic official tutorial:
https://docs.wso2.com/display/ESB500/Sending+a+Simple+Message
I have done the following operation:
1) I have created a new ESB Solution Project.
2) On the "main" project named SampleServices (at this time I am using the same name of the tutorial) I have registered the endpoint to my external web service (New -> Endpoint).
3) Then on this project I have add a new RESP API (New -> REST API). Differently from the tutorial I have enable POST request instead of GET into the API Resource properties because I need to send a POST request containing a payload instead the tutorial GET request. This is my settings:
4) Then, as done in the tutorial, I have setted the send mediator and on this mediator I have setted the defined endpoint pointing at my external web service that have to handle the POST request and retrieve its payload.
Ok, now my problem is: how can I put a mocked XML document into the body of my POST request sended by my *send mediator**?
Reading this second tutorial:
https://docs.wso2.com/display/ESB500/Routing+Requests+Based+on+Message+Content
I know that I can pass the request payload from outside, for example in this second tutorial perform this CURL call that starts the ESB "process":
curl -v -X POST --data #request.json http://localhost:8280/healthcare/categories/surgery/reserve --header "Content-Type:application/json"
This do a call that pass a JSON as payload. In the previous example works fine but it is not good for me.
I have to mock the XML document payload inside my ESB API flow and not take from an external request performed by CURL because in a second implementationstep it will not be mocked but il will come from a previous step in the chain.
So I need a flow like this:
When my API is called it perform a POST request that send a mocked XML payload. Maybe it is have to be putted into the send mediator but I don't know...
How can I put this XML in the payload of the requeste sended by the send mediator? Where have I to define\write it?

Check this sample:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/services/users" name="ListUsersAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" url-mapping="/*">
<inSequence>
<payloadFactory media-type="json">
<format>{ "persons":[{ "person": { "Id":"1", "givenName":"ajith", "lastName":"vitharana", "age":"25", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email", "value":"ajith#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile",
"value":"111111111" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] }}, {"person":{ "Id":"2", "givenName":"shammi", "lastName":"jagasingha", "age":"30", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email",
"value":"shammi#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile", "value":"2222222222" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] } }] }</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>

Related

Azure APIM : External Backend API Oauth2 authentication with Bearer token integration

We have the current situation:
In Azure API manager we build some APIs based on a Swagger definition.
The provider of the APIs provided us with a client id and secret.
Some of these API calls need to be authenticated with a bearer token which is generated on the provider's API infrastructure with a /token endpoint mentioned above and we want to integrate the authentication flow for these API calls in APIM (since the frontend will be authenticated in another way (CORS probably))
We tried various approaches using all kinds of variations in "OAuth2.0" service configurations in the APIM setting and apply them to the API definitions by We kept getting Unauthorized 401.
As starting point we used https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad, but most of the the explanations we found concerned using AD, which we don't need as far as we understand.
We tried to implement the following OAuth 2.0 Postman Authorization configuration into APIM (which actually works in Postman).
Is there a simple and straight forward way to tell APIM to do a call to the token URL with a given ClientId and secret and add the authorization header with a bearer token to the backend API?
Thanks to Gary for pointing me in the right direction. I'm quiet new to the topic, so my approach might be far from perfect but it works.
I ended up in modifying the inbound policies of the API call and added the following (replace xxxx's with the appropriate settings)
<policies>
<inbound>
//....
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
<set-url>https://xxxxxxxxxx.azurewebsites.net/connect/token</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*.*</value>
</set-header>
<set-body>
#("grant_type=client_credentials&scope=xxxxxx&client_id=xxxxxxxx&client_secret=xx")
</set-body>
</send-request>
<set-variable name="bearerToken" value="#(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["access_token"].ToString())" />
<set-header name="Authorization" exists-action="override">
<value>#("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*/*</value>
</set-header>
</inbound>
Short explanantion
A new request is initaited which response will be stored in the variable (token state)
The method is defined as POST
Headers for the request are set (Centent-Type & Accept)
The body of the request is defined
Since the response of the token request (stored in tokenstate) is JSON formatted, the response of the request is cast to a JObject and the "access_token" is stored in the "bearerToken" variable (alternatively you could do without assigning the variable and put this line immediately in the next step.
Set the "Autorization" header with the value "Bearer " + [bearerToken]
the additional steps (Set header Content-Type & Accept) I needed to be able to debug, but in normal cases they will be added by the requesting client of the API.
Yes - you can do this and here is a Curity resource that follows a similar process:
Make an OAuth request to get a JWT based on an incoming credential
Forward it to the downstream API
Cache the result for subsequent requests with the same incoming credential
Your case is a little different but uses the same building blocks. You just need to adapt the OAuth message to use the Client Credentials flow.

Send XML request from Rails application. XML model payment implementation

I am working on the implementation of a payment system on my website. But as the payment system works according to the old model, all requests go through XML. I need to send XML (the code is attached below) to the URL and get a response. How could i send XML post request with Ruby on Rails. I need to send in to this url https://setmpos.ykb.com/PosnetWebService/XML?xmldata=%3CposnetRequest%3E%0D%0A++%3Cmid%3E... Where xmldata is query parametr.
<?xml version="1.0" encoding="ISO-8859-9"?>
<posnetRequest>
<mid>6700000067</mid>
<tid>67000067</tid>
<tranDateRequired>1</tranDateRequired>
<sale>
<amount>2451</amount>
<ccno>4506349116608409</ccno>
<currencyCode>TL</currencyCode>
<cvc>000</cvc>
<expDate>0703</expDate>
<orderID>1s3456z8901234567890123</orderID>
<installment>00</installment>
</sale>
</posnetRequest>

Error: ExchangeImpersonation SOAP header must be present for this type of oauth token

I am trying to use Exchange Web Services (EWS) with application and OAuth2 authentication.
What I did:
registered on Azure portal application, granted all required permissions (even full_access_as_app for Exchange); accepted these permissions as an admin;
prepared correct OAuth2 Bearer token (with scope https://outlook.office365.com/.default);
prepared SOAP request with SOAP UI. As basis for this request I use this one: https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getattachment-operation . Additionally I've added HTTP Authorization header with Bearer token, X-AnchorMailbox with target mailbox.
As a result I get this one: "ExchangeImpersonation SOAP header must be present for this type of OAuth token". I cannot understand what should I do to fix it.
Even tried with ExchangeImpersonate and SmtpAddress with the same mailbox address as above but in this way I get another error "Mailbox not found". But mailbox is! (tested on several mailboxes).
My questions is: what am I doing wrong with EWS?
Request:
POST https://outlook.office365.com/ews/Exchange.asmx
Authorization: Bearer <token>
X-AnchorMailbox: mailbox#something.onmicrosoft.com
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <soap:Header>
        <t:RequestServerVersion Version="Exchange2016"/>
        <t:ExchangeImpersonation>
            <t:ConnectingSID>
                <t:PrimarySmtpAddress>
                    mailbox#something.onmicrosoft.com
                </t:PrimarySmtpAddress>
            </t:ConnectingSID>
        </t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <GetAttachment xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
      <AttachmentShape/>
      <AttachmentIds>
        <t:AttachmentId Id="AAMkADAwNzdjNTg3LTc4M2ItNDE0Yi05MTk4LTQxZDBlYTc1NmMxZgBGAAAAAAAiixtLGariQY7rf5pAKRZZBwBVk8babsuEQ4s2Znfj9fB5AAAAAAEMAABVk8babsuEQ4s2Znfj9fB5AADq3B14AAABEgAQAKZOAcjZCBxHpqvY6XmXp5w="/>
      </AttachmentIds>
    </GetAttachment>
  </soap:Body>
</soap:Envelope>
Response:
ErrorNonExistentMailbox The SMTP address has no mailbox associated with it.
This fixed it for me.
_exchangeService.ImpersonatedUserId =
new ImpersonatedUserId(ConnectingIdType.SmtpAddress, userEmailAddress);
You would need to instantiate impersonation as below:
var ews = new Rebex.net.Ews();
ews.Connect(outlook.office365.com);
ews.Settings.Impersonation = new EwsImpersonation();
ews.Settings.Impersonation.SmtpAddress = <mailbox address>;

Access fields from an http response by parsing the response

I got an XML Response
<?xml version="1.0"?>
<List>
<type>MAILBOX</type>
<DOCS>
<DocId>39fece005f28qrn8000003r5</DocId>
<DocNo>123</DocNo>
</DOCS>
<DOCS>
<DocId>39fece005f28qrn8000003r6</DocId>
<DocNo>456</DocNo>
</DOCS>
</List>
I need to parse it so that I can use it and access DocId; what should be proper code to access docid?
You need to set up parsing on the HTTPRequest node, on the Response Message Parsing tab you select XMLNSC as the message domain, then on the output terminal you can use another Compute node and access the parts of the message as normal in ESQL, e.g.: InputBody.List.DOCS[1].DocId

using wslite in grails returning client - Internal Error

I have an xml that I am trying to send via wslite to my service. My service endpoint, lets call it https://development.net/InquiryService
Now when I send the following call through soapUI, I get the correct response
<soapenv:Envelope //my header information>
<soapenv:Header>
<wsec:Security>
<wsec:PartnerToken>
<wsec:PartnerId>xxxx</wsec:PartnerId>
<wsec:Password>yyyy</wsec:Password>
</wsec:PartnerToken>
</wsec:Security>
</soapenv:Header>
<soapenv:Body>
<acc:retrieveUserAccount>
<acc:SystemInfo>
<sys:ServiceContext>
<sys:transactionId>123</sys:transactionId>
<sys:sourceLogicalId>zzzz</sys:sourceLogicalId>
</sys:ServiceContext>
</acc:SystemInfo>
<acc:accessRegistration>
<acc1:userId>xxxx</acc1:userId>
</acc:accessRegistration>
</acc:retrieveUserAccount>
</soapenv:Body>
</soapenv:Envelope>
When I send the service request through grails, using
withSoap(serviceURL:"https://development.net/InquiryService"){
def response = send {
serviceRequest
}
}
I get wslite.soap.SOAPFaultException: env:Client - Internal Error
I have validated the xml is EXACTLY the same, so I'm not sure why this isn't working.
I think the issue is I need to add my wsdl somewhere, but where?
If the serviceRequest variable is a String, the following should work:
def response = send(serviceRequest)
The braces are causing it to pass a closure to send which if serviceRequest is a String you don't want to happen.

Resources