How to get custom SOAP header from WCF service response in Silverlight? - silverlight

I'm trying to get custom response message header in Silverlight application.
on server-side new MessageHeader added to response headers:
OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHeader("headerName", "headerNS", "The header value"));
and I can see this header in Fiddler:
s:Envelope [
xmlns:s=http://schemas.xmlsoap.org/soap/envelope/
]
s:Header
headerName [ xmlns=headerNS ] The
header value
But, I can't find a way to read header value in Silverlight application service callback:
using (new OperationContextScope(proxy.InnerChannel))
{
var headers = OperationContext.Current.IncomingMessageHeaders;
// headers is null :(
}
Does anyone encountered with similar issue?

Getting SOAP headers in responses on Silverlight isn't as easy as it should be. If you use the event-based callbacks, you're out of luck - it just doesn't work. You need to use the Begin/End-style operation call, like in the example below.
void Button_Click(...)
{
MyClient client = new MyClient();
IClient proxy = (IClient)client; // need to cast to the [ServiceContract] interface
proxy.BeginOperation("hello", delegate(IAsyncResult asyncResult)
{
using (new OperationContextScope(client.InnerChannel))
{
proxy.EndOperation(asyncResult);
var headers = OperationContext.Current.IncomingMessageHeaders;
// now you can access it.
}
});
}
Notice that you cannot use the generated client (from slsvcutil / add service reference) directly, you need to cast it to the interface, since the Begin/End methods are not exposed (explicitly implemented) on the client class.

To get headers from http request try to use Client HTTP stack.
The easies way to do it is to register the prefix, for example:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);

Related

How to attach an Authorization header with a token when using Leaflet js

I am using Leaflet in my Angular.js map application. One of my resources requires an authorization header with token. I am using the leaflet-realtime plugin (found here: https://github.com/perliedman/leaflet-realtime) to get map updates and therefore need to be able to specify my header when realtime performs a fetch to get the data.
I first tried using another library, fetch-intercept (found here: https://github.com/werk85/fetch-intercept), to intercept the requests and attach the header, but the interceptor was being ignored. I included a console.log in the interceptor and it was never reached.
After more research, I noticed specifying headers is supposed to be supported: https://github.com/perliedman/leaflet-realtime/pull/83. However, I cannot find an example for how to properly attach an authorization token. Here is what I am currently trying:
this.mapRealtime = L.realtime({
url: this.getRealtimeUrl(),
crossOrigin: true,
headers: {"Authorization": "token"},
type: 'json',
},
However, when I check the Network logging from my web browser (Chrome) debugging console, all I see for the Request Headers is:
Provisional headers are shown
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
and the server returns status 403 with errortype MissingAuthenticationTokenException.
Can anyone provide an example of how to correctly attach the token? Thanks!
The realtime Leaflet only take url or json file path and you will be unable to pass headers(auth) as they have patch for it which is not working. I was facing same issue. What I did is following:
realtime = (L as any).realtime(async function (success, error) {
let geodataJson = await self.updateGeoJson();
success(geodataJson);
}, {
interval: 15 * 1000,
onEachFeature: onEachFeature,......
I have pass funtion to realtime and in that function I called simple API with headers
async updateGeoJson() {
await this.api.getMarkersGeoJson().subscribe((res: any) => {
this.geoData = res;
});
return this.geoData; }
On first call it will not get data in from this function so we also need to load data in this.geoData in ngOnInit before initmap.
For me it is working I know this is just work around but this issue is still in leaflet realtime. Hopefully this will work for you

Set SOAP addressing header in server side CXF service implemenion

I have web service implemented in Apache CXF. Is there way how can I set SOAP header to request (server side) using AddressingProperties?
This works for me:
List<Header> headers = new ArrayList<Header>();
Header messageIDHeader = new Header(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa"), some_messageID, new JAXBDataBinding(String.class));
headers.add(messageIDHeader);
Header relatesToHeader = new Header(new QName("http://www.w3.org/2005/08/addressing", "RelatesTo", "wsa"), some_relatesTo_ID, new JAXBDataBinding(String.class));
headers.add(relatesToHeader);
wsContext.getMessageContext().put(Header.HEADER_LIST, headers);
But I would like to use org.apache.cxf.ws.addressing.AddressingProperties - something like this:
RelatesToType soapRelatesTo = new RelatesToType();
soapRelatesTo.setValue(some_relatesTo_ID);
soapAddressingHeaders.setRelatesTo(soapRelatesTo);
AttributedURIType soapMsgId = new AttributedURIType();
soapMsgId.setValue(some_messageID);
soapAddressingHeaders.setMessageID(soapMsgId);
How can I pass that to request? I am not able to set it through MessageContext
Adding soapAddressingHeaders to MessageContext
messageContext.put("http://www.w3.org/2005/08/addressing", soapAddressingHeaders);
works correctly but I forgot to enable WS-A addressing for CXF:
<jaxws:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
</jaxws:features>

System.Net.HttpWebRequest Does not contain a definition for 'GetResponse' . In Grid App(XAML)

Following code worked perfectly in Console Application in making request and getting response using HttpWebRequest and WebResponse:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com");
WebResponse response = request.GetResponse();
But the same code when written in GridApp(XAML) template, GetResponse() method gave error:
System.Net.HttpWebRequest Does not contain a definition for 'GetResponse' ...
How come? I included HtmlAgilityPack and all using statements. Does WPF/WindowsStoreApp support slightly different version of GetResponse Method? What am I missing?
In case it is a Windows Store App (and not WPF) there is no synchronous GetResponse method in class WebResponse.
You have to use the asynchronous GetResponseAsync instead, e.g. like this:
using (var response = (HttpWebResponse)(await request.GetResponseAsync()))
{
...
}
If you take a look at the WebRequest page, you'll see that some members are marked with a green icon (a suitcase?). Those are "Supported in .Net for Windows Store apps".

CXF wsdl2java, GZip compression, and stub reutilization

I´m using CXF to consume a WebService and, as the responses are quite large, I´m requesting with a gzip "Accept-Encoding" and using GZIPInInterceptor to handle the gziped response. Also my WSDL is very large (360kb) and it takes a long time(+10 seconds) to create the stub, because it has to read and parse the WSDL, so I´m creating the stub once and reusing it.
The problem is, whenever I try to use two different methods the second request gives me an error saying it is expecting the previous request.
To illustrate my problem I created a simple example with this public WebService:
http://www.webservicex.net/BibleWebservice.asmx?WSDL
Without the GZip compression it works fine:
BibleWebserviceSoap bibleService = new BibleWebservice().getBibleWebserviceSoap();
String title = bibleService.getBookTitles();
response.getWriter().write(title);
String johnResponse = bibleService.getBibleWordsbyKeyWord("John");
response.getWriter().write(johnResponse);
I´m able to receive both responses.
Enabling Gzip compression:
BibleWebserviceSoap bibleService = new BibleWebservice().getBibleWebserviceSoap();
//GZIP compression on bibleService
Client client = ClientProxy.getClient(bibleService);
client.getInInterceptors().add(new GZIPInInterceptor());
client.getInFaultInterceptors().add(new GZIPInInterceptor());
// Creating HTTP headers
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Accept-Encoding", Arrays.asList("gzip"));
// Add HTTP headers to the web service request
client.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);
String title = bibleService.getBookTitles();
response.getWriter().write(title);
String johnResponse = bibleService.getBibleWordsbyKeyWord("John");
response.getWriter().write(johnResponse);
When I try to receive the second response I´m getting this exception:
org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://www.webserviceX.NET}GetBookTitlesResponse found. Expected {http://www.webserviceX.NET}GetBibleWordsbyKeyWordResponse.
On my real application I´m getting an exception with the request:
org.apache.cxf.binding.soap.SoapFault: OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'GetAvailabilityRequest' and namespace 'http://schemas.navitaire.com/WebServices/ServiceContracts/BookingService'. Found node type 'Element' with name 'ns4:PriceItineraryRequest' and namespace 'http://schemas.navitaire.com/WebServices/ServiceContracts/BookingService'
My sample project can be downloaded here:
http://www.sendspace.com/file/plt0m4
Thank you
Instead of setting the protocol headers directly like that, use CXF's GZIPOutInterceptor to handle that.
Either that or reset the PROTOCOL headers for each request. When set like that, the headers map gets updated as the request goes through the chain. In this case, the soapaction gets set. This then gets resent on the second request.

How to know if a Kohana request is an internal one?

I'm writing an API using Kohana. Each external request must be signed by the client to be accepted.
However, I also sometime need to do internal requests by building a Request object and calling execute(). In these cases, the signature is unnecessary since I know the request is safe. So I need to know that the request was internal so that I can skip the signature check.
So is there any way to find out if the request was manually created using a Request object?
Can you use the is_initial() method of the request object? Using this method, you can determine if a request is a sub request.
Kohana 3.2 API, Request - is_initial()
It sounds like you could easily solve this issue by setting some sort of static variable your app can check. If it's not FALSE, then you know it's internal.
This is how I ended up doing it: I've overridden the Request object and added a is_server_side property to it. Now, when I create the request, I just set this to true so that I know it's been created server-side:
$request = Request::factory($url);
$request->is_server_side(true);
$response = $request->execute();
Then later in the controller receiving the request:
if ($this->request->is_server_side()) {
// Skip signature check
} else {
// Do signature check
}
And here is the overridden request class in application/classes/request.php:
<?php defined('SYSPATH') or die('No direct script access.');
class Request extends Kohana_Request {
protected $is_server_side_ = false;
public function is_server_side($v = null) {
if ($v === null) return $this->is_server_side_;
$this->is_server_side_ = $v;
}
}
Looking through Request it looks like your new request would be considered an internal request but does not have any special flags it sets to tell you this. Look at 782 to 832 in Kohana_Request...nothing to help you.
With that, I'd suggest extending the Kohana_Request_Internal to add a flag that shows it as internal and pulling that in your app when you need to check if it is internal/all others.
Maybe you are looking for is_external method:
http://kohanaframework.org/3.2/guide/api/Request#is_external
Kohana 3.3 in the controller :
$this->request->is_initial()
http://kohanaframework.org/3.3/guide-api/Request#is_initial

Resources