Silverlight WCF issue with cross-domain policy file - wcf

Ive seen a number of threads on this issue but none have worked for me. I have a simple silverlight application. I consume a WCF service. When I call a method GetOrderList from the service I get the following error:
An error occurred while trying to make a request to URI 'https://testserver2.mydomain.org/ORDERNET/WCFServices/OrderService/OrderService.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.
Here is my code:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
ServiceReference1.ServiceClient sc = new ServiceReference1.ServiceClient();
sc.GetOrderListAsync("testuser");
sc.GetOrderListCompleted += new EventHandler<ServiceReference1.GetOrderListCompletedEventArgs>(sc_GetOrderListCompleted);
}
void sc_GetOrderListCompleted(object sender, ServiceReference1.GetOrderListCompletedEventArgs e)
{
var RESULT = e.Result;
}
}
This is my client access policy file that I put on my wwwroot:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
When I run fiddler, it finds the "clientaccesspolicy.xml" with a 200 OK (text/xml) so I know is finding the file.
What could be the issue? Do I have an invalid policy file? If I create a console application and consume the service, I can call the method with thno problem.
Any ideas?

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Silverlight Cross Domain Web Service Access Error - This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place
thanks.....

I had similar issue but with service having http protocol, which was solved using .clientconfig file.

I notice you are using HTTPS (https://testserver2.mydomain.org/ORDERNET/WCFServices/OrderService/OrderService.svc)
Have you tried explicitly adding a https://* uri to your cross domain policy file:
<domain uri="https://*"/>
If you need to support http, then add both:
<domain uri="http://*"/>
<domain uri="https://*"/>

Related

Cross-domain error Silverlight + WCF

I have read most of the topics covering cross-domain error and still cannot get it working. Within the website, I load Silverlight module which communicates with WCF Webservice. On localhost, it works fine, no error occurred.
I have Webservice hosted on http://localhost:50283 and in the same folder that port 50283 refers to I have clientaccesspolicy.xml located which looks as follows
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
I placed clientaccesspolicy.XML hardly everywhere including \wwwroot but that brought no effect anyway. I can access clientaccesspolicy.xml both on local and on a different computer within the same network (http://computerIP:50283/clientaccesspolicy.xml displays content). I tried to intercept error in order to find out some more details about error's nature but fiddler does not enlist any error, the only browser does. Literally, I tried everything and still no change. Has anyone faced a similar issue and could provide some hints where I should seek for a solution?
I ran into similar topic with no solution as well, alas
Silverlight-to-WCF cross-domain exception, but clientaccesspolicy.xml is being read successfully
I remember running into this many years ago and solving it a bit differently, namely with a behavior. Consider the following:
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.Xml;
internal class CrossDomainServiceBehavior : BehaviorExtensionElement, IEndpointBehavior
{
private ServiceHost serviceHost;
public override Type BehaviorType
{
get { return typeof(CrossDomainServiceBehavior); }
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
if (serviceHost == null)
{
serviceHost = new ServiceHost(typeof(CrossDomainPolicyService));
string address = new Uri(endpoint.Address.Uri, "/").ToString();
ServiceEndpoint crossDomainEndpoint = serviceHost.AddServiceEndpoint(typeof(ICrossDomainPolicyService), new WebHttpBinding(), address);
crossDomainEndpoint.Behaviors.Add(new WebHttpBehavior());
serviceHost.Open();
}
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
protected override object CreateBehavior()
{
return new CrossDomainServiceBehavior();
}
}
internal class CrossDomainPolicyService : ICrossDomainPolicyService
{
public Message ProvideClientAccessPolicyFile()
{
XmlReader xmlReader = CreateClientAccessXml();
return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
}
public Message ProvideCrossDomainPolicyFile()
{
XmlReader xmlReader = CreateCrossDomainXml();
return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
}
private static XmlReader CreateClientAccessXml()
{
TextReader reader = new StringReader(#"<?xml version='1.0' encoding='utf-8'?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers='*' >
<domain uri='*'/>
</allow-from>
<grant-to>
<resource path='/' include-subpaths='true'/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>");
return XmlReader.Create(reader);
}
private static XmlReader CreateCrossDomainXml()
{
TextReader reader = new StringReader(#"<?xml version='1.0'?>
<cross-domain-policy>
<allow-http-request-headers-from domain='*' headers='*'/>
</cross-domain-policy>");
return XmlReader.Create(reader);
}
}
The CrossDomainServiceBehavior needs to be added to the behaviors on your WCF service and it uses the CrossDomainPolicyService for dynamically adding the cross domain policy. This prevents you from having to add the cross domain file to the website itself.
Adding the behavior from code (for example with self hosted services):
endPoint.Behaviors.Add(new CrossDomainServiceBehavior());
Or in case of WCF definitions in config:
For the sake of this example I will assume the CrossDomainServiceBehavior is in the namespace Services.CrossDomainServiceBehavior and the assembly it is located in is version 1.0.0.0 with a neutral culture. It also assumes you have a binding on your service declaration called webHttp.
Registering the behavior:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="CrossDomainServiceBehavior" type="Services.CrossDomainServiceBehavior, CrossDomainServiceBehavior.AssemblyName, Version=1.0.0.0, Culture=neutral" />
</behaviorExtensions>
</extensions>
Declare the behavior:
<behaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp/>
<CrossDomainServiceBehavior/>
</behavior>
</endpointBehaviors>
<behaviors>
Add the behavior to the binding (here as example one called webHttp):
<bindings>
<webHttpBinding>
<binding name="webHttp"
maxReceivedMessageSize="20000000" >
<security mode="None">
<transport clientCredentialType = "None"/>
</security>
</binding>
<CrossDomainServiceBehavior />
</webHttpBinding>
</bindings>
Finally, add the behavior to your service endpoint, here in example one that implements ISomeService:
<endpoint address="" binding="webHttpBinding" contract="Services.ISomeService" bindingConfiguration="webHttp" behaviorConfiguration="CrossDomainServiceBehavior "/>
Not sure if it has to do anything with it, but I have a similar setup and my clientaccesspolicy.xml looks a bit different.
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="http://*"/>
<domain uri="https://*" />
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Especially the splitting of http and https adresses is different.
Besides that you are trying to do this with a non-default port, have you tried it on the default port 80? oh and on the production environment those *'s are replaced with the actual domain name.

Handle Fault string message if end point not exits in wsdl

I am getting the below exception when trying to call service from SOAPUI that is fine
because message part element dose not exits in wsdl.
But I want to handle in proper way in CXF web service and send proper fault string instead of below message ex: "Bad Request"
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing"/>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:109a84f4-373d-4406-9087-82bd58bea394</MessageID>
<To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
<RelatesTo xmlns="http://www.w3.org/2005/08/addressing">uuid:3dcf9e26-20fc-4c93-bc01-8ca9ab1ae2eb</RelatesTo>
</soap:Header>
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Message part Reservation was not recognized. (Does it exist in service WSDL?)</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Does any one know in cxf where I can handle in proper way ?
You can solve this problem by consuming the web service from a client application. Everywhere you need to consume the WS, should put a BindingProvider to the port. This example is a method of:
...
import javax.xml.ws.BindingProvider;
public class WSClient {
public String getUserName(int userCode) {
WebServiceAuth ss = new WebServiceAuth();
IWebServiceAuth port = ss.getPort(IWebServiceAuth.class);
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider
.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:8081/WebServiceAuth/WSAuth");
return port.getUserName(userCode);
}
}
In this case you need to put your service's address into the BindingProvider.

Apigee Pre-Flight Options Requests

I create api proxies and check the box that says "Enable Direct Browser Access for Your API — Allow direct requests from a browser via CORS." but my OPTIONS requests are still failing with :
{
"fault": {
"faultstring": "Received 405 Response without Allow Header",
"detail": {
"errorcode": "protocol.http.Response405WithoutAllowHeader"
}
}
}
From what I understand about CORS Pre-Flight Options requests, the client first sends the OPTIONS request to the server as a safeguard for "safe" CORS. This request should return a response with the list of request types that are available.
My Question: How do I make it so that Apigee responds correctly to OPTIONS requests and does not pass the OPTIONS request to my api behind the proxy?. If it helps I have AngularJS javascript apps trying to communicate with my Apigee endpoint.
Javascript errors:
OPTIONS http://api.example.com No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://client.example.com' is therefore not allowed access.
XMLHttpRequest cannot load http://api.example.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://client.example.com' is therefore not allowed access.
Default "Add CORS" xml
<AssignMessage async="false" continueOnError="false" enabled="true" name="Add-CORS">
<DisplayName>Add CORS</DisplayName>
<FaultRules/>
<Properties/>
<Add>
<Headers>
<Header name="Access-Control-Allow-Origin">*</Header>
<Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept</Header>
<Header name="Access-Control-Max-Age">3628800</Header>
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>
Default Proxy Endpoints xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows/>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<HTTPProxyConnection>
<BasePath>/v1/cnc</BasePath>
<VirtualHost>default</VirtualHost>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</ProxyEndpoint>
Default Target Endpoint xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="default">
<Description/>
<Flows/>
<PreFlow name="PreFlow">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
</PreFlow>
<HTTPTargetConnection>
<URL>http://api.example.com/v1/assets.json</URL>
</HTTPTargetConnection>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</TargetEndpoint>
Since you don't want the OPTIONS request to pass through to the backend API, there are two things needed:
A RouteRule to a null target with condition for the OPTIONS request. Notice there is no TargetEndpoint specified.
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS"</Condition>
</RouteRule>
A custom flow in the ProxyEndpoint to handle the CORS response. Since the new RouteRule sends the message to a null Target (echoes request back to client), the message will not route to the 'default' TargetEndpoint where the CORS policy currently is defined.
An updated version of your ProxyEndpoint would look like the below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows>
<Flow name="OptionsPreFlight">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
<Condition>request.verb == "OPTIONS"</Condition>
</Flow>
</Flows>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<HTTPProxyConnection>
<BasePath>/v1/cnc</BasePath>
<VirtualHost>default</VirtualHost>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS"</Condition>
</RouteRule>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</ProxyEndpoint>
NOTE: The RouteRules are evaluated in the order specified in the ProxyEnpoint configuration. You should always have the default (no condition) Route at the end. Otherwise, if at the top, it will always match and never evaluate the other Route possibilities.
I did the same thing mentioned in the above answer but still getting the same issue. Then after doing some research issue was solved.
The issue was that the cors header response was not passed as header during request. To solve that you can do is adding the cors value in proxy endpoint preflow as well:
<PreFlow name="PreFlow">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
</PreFlow>

Paypal sandbox endpoint webservice - Error "You do not have permissions to make this API call"

I used this paypal endpoint webservice for my PHP5 SoapClient :
Sandbox API Signature SOAP https://api-3t.sandbox.paypal.com/2.0/
And when i send my soap request with my credentials, i get an error with :
Ack => failure
ErrorCode => 10002
Short message => Authentication/Authorization failed
Long message => You do not have permissions to make this API call
This is current Soap message send to soap paypal API :
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:ebay:apis:eBLBaseComponents"
xmlns:ns2="ebl:SetExpressCheckoutRequestDetails"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns3="urn:ebay:api:PayPalAPI"
xmlns:ns4="ebl:UserIdPasswordType">
<SOAP-ENV:Header>
<ns3:RequesterCredentials xsi:type="ns4:UserIdPasswordType">
<Username>xxxxx</Username>
<Password>xxxxx</Password>
<Signature>xxxxx</Signature>
</ns3:RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns3:SetExpressCheckoutReq>
<ns3:SetExpressCheckoutRequest>
<ns1:Version>84.0</ns1:Version>
<ns1:SetExpressCheckoutRequestDetails
xsi:type="ns2:SetExpressCheckoutRequestDetailsType">
<ReturnUrl>url_to_/success.paypal.php</ReturnUrl>
<CancelUrl>url_to_/cancel.paypal.php</CancelUrl>
<LocaleCode>US</LocaleCode>
</ns1:SetExpressCheckoutRequestDetails>
</ns3:SetExpressCheckoutRequest>
</ns3:SetExpressCheckoutReq>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I instantiated this PHP5 SoapClient :
//Endpoint
$location = 'https://api-3t.sandbox.paypal.com/2.0/';
$uri = 'urn:ebay:api:PayPalAPI';
//SoapClient options
$options = array('trace' => 1, 'exceptions' => 1, 'location'=>$location, 'uri'=>$uri);
//My Soap Client
$client =new SoapClient('https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl',$options);
But when I called SetExpressCheckout paypal soap service, i receive the following soap message :
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cc="urn:ebay:apis:CoreComponentTypes"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"
xmlns:ed="urn:ebay:apis:EnhancedDataTypes"
xmlns:ebl="urn:ebay:apis:eBLBaseComponents"
xmlns:ns="urn:ebay:api:PayPalAPI">
<SOAP-ENV:Header>
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext"
xsi:type="wsse:SecurityType"></Security>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI"
xsi:type="ebl:CustomSecurityHeaderType">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents"
xsi:type="ebl:UserIdPasswordType">
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body id="_0">
<SetExpressCheckoutResponse xmlns="urn:ebay:api:PayPalAPI">
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">
2012-01-13T12:09:01Z
</Timestamp>
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack>
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">
c8d551f118a1
</CorrelationID>
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType">
<ShortMessage xsi:type="xs:string">
Authentication/Authorization Failed
</ShortMessage>
<LongMessage xsi:type="xs:string">
You do not have permissions to make this API call
</LongMessage>
<ErrorCode xsi:type="xs:token">10002</ErrorCode>
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">
Error
</SeverityCode>
</Errors>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">84.0</Version>
<Build xmlns="urn:ebay:apis:eBLBaseComponents">2271164</Build>
</SetExpressCheckoutResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Nevertheless, I used the API credentials of my business account test...
I don't understand why my code doesnt work.
The error is : 'You do not have permissions to make this API call', but how it's possible? Because i use the correct endpoint service (sandbox) ?

Cross Domain Policy

I am working with a Silvelright App that consumes a WCF service, I have placed a crossdomain and clientaccesspolicy xml's in the wwwroot of the IIS as well as in the application folder!
yet when the client communicates with the service, it throws an error saying;
An error occurred while trying to make a request to URI ‘http://localhost:1528/MyService.svc’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a ……
Please help!
Thanks
The clientaccesspolicy.xml needs to be on the same port as your service. It needs to be located at http://localhost:1528/clientaccesspolicy.xml
If you are self hosting the WCF service then you need to host the clientaccesspolicy.xml from within your WCF service. The easiest way I've found to do this is to add a separate service contract that provides an HTTP GET of the clientaccesspolicy.xml.
[ServiceContract()]
public class PolicyRetriever
{
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
public Stream GetSilverlightPolicy()
{
string result = #"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers=""*"">
<domain uri=""*""/>
</allow-from>
<grant-to>
<resource path=""/"" include-subpaths=""true""/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
if (System.ServiceModel.Web.WebOperationContext.Current != null)
{
System.ServiceModel.Web.WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
}
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
}