Issue:
An issue exists whereby I cannot access my Self Hosted ADO.NET Data Services from my RIA applications.
My services are hosted separately to the web projects with the Rich Internet Applications (RIA)s.
I need to enable access from separate Silverlight (and Flash) client apps.
From Silverlight I get an exception (see below) when I try to make a call to the ADO.NET Data Service (which is Self Hosted separately). This I believe to due to Silverlight forbidding the cross domain call.
System.InvalidOperationException: An error occurred while saving changes. See the inner exception for details. --->
System.Data.Services.Http.WebException: Internal error at 'HttpWebResponse.NormalizeResponseStatus'.
at System.Data.Services.Http.HttpWebResponse.NormalizeResponseStatus(Int32& statusCode)
at System.Data.Services.Http.HttpWebResponse..ctor(HttpWebRequest request, Int32 statusCode, String responseHeaders)
at System.Data.Services.Http.HttpWebRequest.CreateResponse()
at System.Data.Services.Http.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Data.Services.Client.BaseAsyncResult.EndExecute[T](Object source, String method, IAsyncResult asyncResult)
at System.Data.Services.Client.QueryAsyncResult.EndExecute[TElement](Object source, IAsyncResult asyncResult)
at System.Data.Services.Client.DataServiceQuery`1.EndExecute(IAsyncResult asyncResult)
at Curo.Silverlight.MainPage.<>c__DisplayClass1.<.ctor>b__0(IAsyncResult ar)
at System.Data.Services.Client.BaseAsyncResult.HandleCompleted()
at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult)
at System.Data.Services.Http.HttpWebRequest.ReadyStateChanged()
System.Data.Services.Http.WebException: Internal error at 'HttpWebResponse.NormalizeResponseStatus'.
at System.Data.Services.Http.HttpWebResponse.NormalizeResponseStatus(Int32& statusCode)
at System.Data.Services.Http.HttpWebResponse..ctor(HttpWebRequest request, Int32 statusCode, String responseHeaders)
at System.Data.Services.Http.HttpWebRequest.CreateResponse()
at System.Data.Services.Http.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Data.Services.Client.QueryAsyncResult.AsyncEndGetResponse(IAsyncResult asyncResult)
Notes:
From what I have read, it appears that cross domain access is forbidden with regards to ADO.NET Data Services, which may result in my having to take another approach to the data access e.g. using a pure REST Framework..?
"The problem of Cross Domain ADO.NET
Data Services is more complex than it
sounds and it hasn't been solved.
I've discussed it with Microsoft for a
while now and the reason that it
doesn't work has to do with its using
a browser level transport and that
transport doesn't allow cross-site
scripting."
See:
http://forums.silverlight.net/forums/p/70925/170703.aspx#170703
I understand that I need may need to expose a ClientAccessPolicy.xml file which will define the access rules whilst restricting cross site scripting.
It is also noteworthy to mention that the RIA applications will be running on the same LAN.
Questions:
Is there a viable means for me to access the services from my RIA clients considering they will be running behind the same firewall? If so how?
How do I expose ClientAccessPolicy.xml from a Self Hosted ADO.NET Data Service exactly?
What way would you recommend proceeding in order to allow external access to my services?
- Different REST Framework?
- Host Services within same web project at the cost of separation?
- Any other advice...
Thanks.
I'm not sure I understand the full breadth of your problem, but at the very least, I would make sure I had a clientaccesspolicy.xml file and a crossdomain.xml file in the root folder of the service. It's important for the xml policy files to be in the root folder of the domain. For example, if your service is hosted in mycompany.com/services, the xml files need to be in the mycompany.com folder, not the services folder.
Here's an example of the ClientAccessPolicy.xml:
<?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 include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
And here's an example of the crossdomain.xml:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*" />
</cross-domain-policy>
I would recommend using both files for both flash and silverlight. Both files above will allow open access from all flash and silverlight apps, but that shouldn't be a problem if you're behind a firewall.
I had this exact problem in one of my behind-the-firewall silverlight apps and putting these files in place seemed to fix the problem. I would start with these files and go from there.
"The problem of Cross Domain ADO.NET Data Services is more complex than it sounds and it hasn't been solved. I've discussed it with Microsoft for a while now and the reason that it doesn't work has to do with its using a browser level transport and that transport doesn't allow cross-site scripting."
See: http://forums.silverlight.net/forums/p/70925/170703.aspx#170703
The cross domain policy is required by (as shown in the answer by Ben McCormack above).
By utilizing Yahoo pipes which is set up to allow cross domain access to aggregated feeds, you may be able to consume and external ADO.NET Data Services (formerly Astoria, now OData) from within a Silverlight application.
You will most likely lose the fidelity of querying the dataset that Odata gives you, but this could be recreated in the yahoo pipes.
The issue was not with the ADO.NET data services (OData), its was with Silverlight as does not allow cross domain calls.
Related
I've developed .an application using Silverlight and WCF Ria Services.
The application must be host on windows XP machine that uses IIS 5. Due the information i found on web I did deploy application without any problems. But now when my application tries to execute first WCF query I've faced this error :
Message: Unhandled Error in Silverlight Application Load operation
failed for query 'Login'. [HttpWebRequest_WebException_RemoteServer]
Arguments: NotFound Debugging resource strings are unavailable. Often
the key and arguments provide sufficient information to diagnose the
problem. See
http://go.microsoft.com/fwlink/?linkid=106663&Version=5.1.10411.0&File=System.Windows.dll&Key=HttpWebRequest_WebException_RemoteServer
at
System.ServiceModel.DomainServices.Client.OperationBase.Complete(Exception
error) at
System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationOperation.End(IAsyncResult
result) at
System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationOperation.<>c_DisplayClass1.b_0(Object
state) at
System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationOperation.RunInSynchronizationContext(SendOrPostCallback
callback, Object state) at
System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationOperation.HandleAsyncCompleted(IAsyncResult
asyncResult) at
System.ServiceModel.DomainServices.Client.AsyncResultBase.Complete()
at
System.ServiceModel.DomainServices.Client.ApplicationServices.WebAuthenticationService.HandleOperationComplete(OperationBase
operation) at
System.ServiceModel.DomainServices.Client.LoadOperation.<>c_DisplayClass41.<Create>b__0(LoadOperation1
arg) at
System.ServiceModel.DomainServices.Client.LoadOperation`1.InvokeCompleteAction()
at
System.ServiceModel.DomainServices.Client.OperationBase.Complete(Exception
error) at
System.ServiceModel.DomainServices.Client.LoadOperation.Complete(Exception
error) at
System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult
asyncResult) at
System.ServiceModel.DomainServices.Client.DomainContext.<>c_DisplayClass1b.b__17(Object
)
How can I fix this error ?
Application hosted successfully on IIS 7 on windows 7 machine and wcf ria did work too.
Update : After using Fiddler I found my application's error is 404 , Silverlight can't find Ria Services .
NotFound means any error on the server in this case. You need to get detailed WCF logs.
I'd recommend you to add the following to the web.config file to enable WCF logging:
<configuration>
... your regular configuration here ...
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="All" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\wcflogs\your_wcf_service_log.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
Then you can open .svclog file with Service Trace Viewer Tool (SvcTraceViewer.exe)
and see what happened in detail.
Try to re install RIA Services on server.
I think the command was
RiaService.msi Server=true
after reinstalling, try to access your service directly on web browser. the URL of your Service will be http://YOURDOMAIN.COM/YourAPP/Full-NameSpace-Of-Class.svc
in the namespace, you will have to change dots (.) by dashes(-)
if it doesn't return response, then you have to verify that WCF is installed and registered with IIS.
after one day of thorough searching for solutions, I'm at a standstill over the following issue:
I am adding a aspx-page with silverlight app as a feature to my sharepoint.
The app accesses the sparql-endpoint from a virtuoso service and works fine outside of sharepoint. clientaccesspolicy.xml is added to the virtuoso and sharepoint root. Both are accessible over http:
<?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>
I even added crossdomain.xml in both locations after this problem crept up on my and added both files explicitly to the sharepoint path via central-admin.
I'm still getting a securityException...
Please help me with this,
thanks in advance.
After some several more hours wasted, I hammered it out on my own.
For anyone arriving at the same crossroad:
If you are certain that crossdomain.xml is in place and you silverlight app works outside of sharepoint, this specific security-exception stems not from a cross-domain violation, but more likely from one of the other url access restrictions documented here:
As it is stated there:
'When users get an error that results from one of these access policies being violated, the error may not indicate the exact cause.'
This error might have any of the listed causes. (a major negligence of msdn in my opinion)
Since 'Cross-scheme access' and 'Cross domain-access' is out of the picture, this leaves only a 'Cross zone-access violation'. This means your Silverlight app and the service endpoint got to be in the same zone to be allowed to communicate (e.g. Internet or Intranet). Since my SPAQL-endpoint is hosted at localhost for now (an Intranet address as default in IE) and my sharepoint address http: //my.comp.name is by default in the Internet-zone this error was thrown.
To get rid of this error you have to either host your endpoint on an Internet-address or place your sharepoint address in the Intranet-zone manually.
After some more googeling I found the right configuration in the Internet-options.:
->security ->local Intranet -> sites ->add:your sharepoint address (http: //my.comp.name)
That's it, hope I saved you some lasting wrinkles.
take care...
I'm hosting a Silverlight Business Application Template derived application on an IIS Server. I'm using the built-in Forms Authentication which is working perfectly.
Unfortunately, I've added an additional service which has peculiar behavior. If I remote into the server and use the site everything works as expected. If I connect to the site from another PC, Authentication still works but my custom Domain Service is failing with the following error:
IE Throws this Error Message:
System.ServiceModel.DomainServices.Client.DomainOperationException:
Load operation failed for query
'Get___'. Exception of type
'System.ServiceModel.DomainServices.Client.DomainOperationException'
was thrown.
I tried debugging the process and get a little more information:
System.ServiceModel.DomainServices.Client.DomainOperationException:
Load operation failed for query
'Get___'. The remote server returned
an error:NotFound. --->
System.ServiceModel.CommunicationException:
...
My clientaccesspolicy and crossdomain policies are in both wwwroot and the root of the website and are the following:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*" />
<domain uri="http://*" />
<domain uri="https://*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
The Domain Service that's failing is using an ADO.NET Entity Model. The entities of which are in the same the aspnetdb database that is used for authentication and I've granted file permissions for the IIS User (and Administrator, I got desperate) for the App_Data folder which contains the db.
Again, all services work if connecting locally on the server. Only the Auth/Registration services works when connecting remotely.
I've searched for two days and tried every solution I can find but can't seem to get it working. Any advice or direction would be greatly appreciated.
Although this is pretty late for your project but it might help somebody else. Sounds like you are having problem with authenticating to the underlying database. You may want to look into what sort of impersonations are happening at database level.
I had a similar problem, and it turned out that I was trying to access the database as Sliverlight client pc account which never existed in authorized accounts (although my authentication was working perfectly just like in your case). Changing the Application Pool Identity fixed it for me (I was using Network Service account on a PC joined to a domain which uses Computer$ account to login on your behalf)
When you run into CommunicationException, you really want to look at InnerException which will tell what is the real issue.
If there's nothing then you'll need to debug on server side (step through service) to see what is throwing the exception.
CommunicationException occurs if an Exception is thrown on WCF server side and not wrapped into a fault causing the channel to become faulted (in my limited experience at least).
Hope this helps somebody.
WCF Tracing didn't help me! It gives an Empty message.
Finally,
FOR MY CASE,
I removed [RequiresAuthentication] like attributes from methods
I removed [RequiresAuthentication] from Domain Service Class (check all partials)
If it works on local but not on server it must be a configuration problem. In my case I used membership.ResetPassword() function which is disabled in web.config as enablePasswordReset=false.
Beside this some people says some methods just invoke-able in asp.net.compatibility mode.
Hope helps someone else.
I have 3 sites :
media.lmenaria.com -> Hosting Images
webservice.lmenaria.com -> Sending images url from database.
www.lmenaria.com -> Host Silverlight application and display images.
When I run page "http://www.lmenaria.com/silverlight.aspx". I am getting below exception. So what shpould I do ?
System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState) at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.OpenReadAsyncCallback(IAsyncResult result)
I think, my all sites runing at same domain, so I don't need crossdomain xmls. Please let me know how Can I fix it.
I have tried to put corssdoamin xml media.lmenaria.com,webservice.lmenaria.com both, and working fine, but only at
www.lmenaria.com not working.
We are downloading images using WebClient.
Thanks in advance,
Laxmilal Menaria
Subdomains on the same domains are considered diffrent domain.
Consider the following scenario: http://www.myBank.com and http://api.myBank.com.
In that scenario you want to enable cross domain calls to http://api.myBank.com and strictly block those off to http://www.myBank.com.
You will need to add a ClientAccessPolicy.xml to allow access to the subdomain that hosts the services from the other subdomains (even the WWW subdomain).
Sincerely,
-- Justin Angel
I have a problem to access SharePoint Webservice over Silverlight.
An error occurred while trying to make a request to URI
'http://sample:8000/_vti_bin/Authentication.asmx'.
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.
Please see the inner exception for
more details.
Some questions:
How do I correctly deploy clientaccesspolicy.xml over Sharepoint Designer? Simply open site in designer, add file and then publish?
The site where clientaccesspolicy.xml should be deployed use forms authentication. I wasn't able to use Sharepoint Designer to publish there. Because of that, I created new zone for this site, which use Windows Authentication and published clientaccesspolicy.xml there. Both use same content database, didn't ?
If clientaccesspolicy.xml will be published, how can I allow this file be accessed anonymously?
Regards
Anton Kalcik
Here answers to my question 1. and 2.:
In Sharepoint Designer you open the site over: File -> Open Site -> In text field "Site name:" type URL of your site. Than drag & drop clientaccesspolicy.xml in root of your site.
If you have Form Authentication, you don't need for this step create new zone (but for some reasons it can be useful). You simply open web browser and type URL of your site. Then fill up text fields (always with user that have administrator privileges) and check "Sign me in automatically". After that will Sharepoint designer use this credentials for specified URL.
If you can help me with question Nr. 3, or you have some other solution, how can I access clientaccesspolicy.xml from Silverlight, post it!
The way we handled this on our project was to use an HTTP Handler. We put the clientaccesspolicy.xml file in the _layouts directory (which is shared across sharepoint sites) using a feature (you can also just manually copy it there).
Then we added our HTTP handler to the web.config handlers section. In our handler we check to see if the request is for /clientaccesspolicy.xml and if so we rewrite the path:
if (path.ToLowerInvariant() == "/clientaccesspolicy.xml")
{
HttpContext.Current.RewritePath("/_layouts/clientaccesspolicy.xml");
}
I'm not sure if this will bypass the security so it might not fully address your issue. But at least it gives you a method to access this file.
That is fine.
It should be, provided you haven't setup a whole new site somehow.
It shouldn't be as that would be a security risk. If you need to authenticate via WindowsAuth for the services so should you for the clientaccesspolicy.xml.
Keep in mind that clientaccesspolicy.xml must be at the domain root. In your example it would have to availble from http://sample:8000/clientaccesspolicy.xml. If you can't open it from your browser at that URL, your Silverlight client won't find it either.
The easiest way to get the file in the right place is to just copy it there via FTP or explorer. The file should be available to anonymous users (read only of course).
I find more realeable way to implement sharepoint httpHandler: it returns all content of clientaccesspolicy.xml himself
public void ProcessRequest(HttpContext context) {
if (context.Request.Path.ToLowerInvariant() == "/clientaccesspolicy.xml") {
context.Response.Write(#"<?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>");
}
}