I have a Silverlight 4 app that is hosted in an ASP Azure web role. The web role exposes a WCF service. (All this is in the same Visual Studio solution.)
I successfully added a reference to the service, and generated client code. However, it causes an error:
ExpenseServiceClient service = new ExpenseServiceClient();
service.GetExpensesCompleted += new EventHandler<GetExpensesCompletedEventArgs>(service_GetExpensesCompleted);
service.GetExpensesAsync();
The callback:
static void service_GetExpensesCompleted(object sender, GetExpensesCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.ToString());
return;
}
// ...
}
e.Error is the following:
{System.ServiceModel.CommunicationException:
An error occurred while trying to make
a request to URI
'http://localhost:88/ExpenseService.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.
---> System.Security.SecurityException --->
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)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at ExpenseCalc_SilverLight.ExpenseService.ExpenseServiceClient.ExpenseServiceClientChannel.EndGetExpenses(IAsyncResult result)
at ExpenseCalc_SilverLight.ExpenseService.ExpenseServiceClient.ExpenseCalc_SilverLight.ExpenseService.IExpenseService.EndGetExpenses(IAsyncResult result)
at ExpenseCalc_SilverLight.ExpenseService.ExpenseServiceClient.OnEndGetExpenses(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)} System.Exception {System.ServiceModel.CommunicationException}
Both of these are running on localhost. What am I doing wrong?
Silverlight expects a ClientAccessPolicy.XML file to be present whenever it makes calls that in considers to be "cross domain" (worded that way b/c its fairly strict). Have you set that up? I'm not a SL expert, but that error normally arises when the policy file is not present.
Easy way is to create one at root of your site, so http://localhost/clientaccesspolicy.xml
A pretty loose "allow all" file is something like:
<?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>
For more complex scenarios (as may arise in Azure, depending on your architecture), you can create an IIS handler to serve up the expected XML, which allows for dynamic creation of the policy based on the request.
There are plenty of resources on this approach should you decide to go for it, but I'd recommend trying to simple one first to make sure that's the issue.
I don't know much about SilverLight, but I've come across mention of cross domain policies when talking about deploying SilverLight apps that use Azure storage. My Google foo is weak, but you might try one of these links.
Related
I am developing an Angular website hosted in Azure that interacts with a separate Web API back-end, also hosted in Azure. I am attempting to use a combination of ASP .Net Identity w/ OAuth Bearer Tokens in the Web API layer for user account login / authentication, and also Azure Active Directory in the website layer, to control access to the application itself, since it's not live and I do not want it to be accessible to the general public.
Everything was working fine, until I added the AAD logic. Now for some reason, after I log-in with a user account via the Web API, I get the following server-side exception in the website for two specific .html files that angular tries load while navigating the user to their account dashboard. I can load these files directly via the URL, and all the other files required by that page seem to load correctly, but these two return this error.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The token received from
AAD was not recognized as a valid JWT.
Source Error:
An unhandled exception was generated during the execution of the current web
request. Information regarding the origin and location of the exception can
be identified using the exception stack trace below.
Stack Trace: [InvalidOperationException: The token received from AAD was not
recognized as a valid JWT.]
Microsoft.Azure.Websites.Authentication.AADAuthenticationModule.OnValidateJwt(String rawToken, Boolean validateNonce) +845
Microsoft.Azure.Websites.Authentication.AADAuthenticationModule.TryAuthenticateFromBearerToken(HttpRequestBase request, IPrincipal& principal) +157
Microsoft.Azure.Websites.Authentication.AADAuthenticationModule.TryAuthenticate(HttpContextBase context, IPrincipal& principal) +34
Microsoft.Azure.Websites.Authentication.AADAuthenticationModule.AuthenticateRequest(HttpContextBase context) +578
Microsoft.Azure.Websites.Authentication.AADAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs e) +80
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.36215
Any help would be greatly appreciated. Thanks!
UPDATE
OK, so I don't know if this is the correct answer to this issue, but I ended up changing my Angular code so that instead of adding the Bearer token to the global headers collection (which angular then transmits with every request, including templates and resources), I now manually add it only for the GET / POST requests to the Web API endpoints.
Was
$http.defaults.headers.common["Authorization"] = 'Bearer ' + token;
Now
_self.Get = function(url, data, token)
{
var _request = {
method: "GET",
url: url,
data: data
};
if (token != null)
{
_request.headers = { 'Authorization': 'Bearer ' + token };
}
return $http(_request);
};
My silverlight application is currently hosted in IIS and is set up to only use HTTPS.
the silverlight web project is the root of the IIS website and the webservices project is a seperate web application mapped to /Services.
I can navigate to my site by using "" and ""
but if I use the second option the site loads fine but I get an error when attempting to access any of my services.
An error occurred while trying to make
a request to URI
'https://localhost/Services/Services/Authentication.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
I have Crossdomain.xml and clientaccesspolicy.xml files in the root of my Web Services application and also within the root of the Silverlight Web project.
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-access-from domain="https://*" secure="true" />
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="https://*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
I'm not really sure what the problem is.
Thanks
Edit
The following is the what fiddler shows after calling the service. .
With fiddler set up to decode https IE didn't show any extra entries, but with chrome I get the following output
As the error message says, "This could be due to attempting to access a service in a cross-domain way..." Try using some tool such as Fiddler in the client to see what is the actual response from the server. That will give you more information about the issue.
As shown by fiddler your reference file for the service are having pointers to localhost:444 this usually happens when you have both projects in same solution and add the service reference.
I resolved this by right clicking on the frontEnd.Web part of my solution, going to properties and then the Web tab, instead of using an auto assign port option, I changed it to use local IIS server. This got rid of the error.
We have a problem with HTTP Response caching when using WCF RIA Services with Silverlight.
Server side, we have a simple DomainService GET method with no caching specified, like this:
[OutputCache(OutputCacheLocation.None)]
public IQueryable<SearchResults> GetSearchResults(string searchText);
The throws a DomainException when the user is not authenticated (i.e. when the FormsAuthenticationCookie expires). This is as designed.
But when the user is re-authenticated, and the Query is called again with the same 'searchText' parameter, then the Query never gets to the server (no breakpoint hit; Fiddler shows no http request sent).
I think this is because when the exception is thrown on the server, the HTTP Response has the 'Cache-Control' property set to 'private', and when the client wants to perform the same query later (once the user is logged in), then the browser does not even send the request to the server.
If we enter a different search parameter, then the query is re-executed no problem.
Is there any way of ensuring the http response always has 'no-caching' - even when it does not return normally?
UPDATE1
The problem only occurs when deployed to IIS - when testing from Visual Studio with either Casini or IIS Express it works fine.
UPDATE2
I updated the question to reflect new knowledge.
You shouldn't be throwing a DomainException for authorization errors. Due to the way Silverlight handles faults, these responses can still be cached by your browser. Instead, throw an UnauthorizedAccessException from your DomainService and that should fix the caching error on the client.
I created one solution and then added one project which contains all WCF services. Then i added it's reference to my Silverlight project in the same solution. Now when i try to debug i get one message box saying This Silverlight project you are about to debug is consuming web services. Calls to the web service will fail unless the project is executed in the context of the web which contains the web service. and still if i run it i get this error :-
An error occurred while trying to make a request to URI 'http://localhost:50318/CustomersService.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.
This is the detailed exception :-
{System.ServiceModel.CommunicationException: An error occurred while trying to make a request to URI 'http://localhost:50318/CustomersService.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. ---> System.Security.SecurityException ---> 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)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at MVVMDemo.CustomersServiceRef.CustomersServiceClient.CustomersServiceClientChannel.EndGetCustomers(IAsyncResult result)
at MVVMDemo.CustomersServiceRef.CustomersServiceClient.MVVMDemo.CustomersServiceRef.ICustomersService.EndGetCustomers(IAsyncResult result)
at MVVMDemo.CustomersServiceRef.CustomersServiceClient.OnEndGetCustomers(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)}
What should i do?
Thanks in advance:)
If your page hosting the silverlight control and the webservice you are trying to connect are in different domains(in ur case it looks like they are different projects) you will need to add the clientaccesspolicy.xml file to your website.
<?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>
Check out this link for more details
I am having trouble upgrading my current project to use RIA Services. I added all the necessary web.config changes but still no luck. I everything compiles fine but when I hit the page using the datacontext I get an error. I debugged with fiddler and I'm getting a 404 on one of the request. I am getting back headers in my grid so some communication is happening but no data is actually coming through. Another thing to note is that my MVC is running windows authentication. I do have a clientaccesspolicy.xml as well.
Error in Silverlight with Headers but no data,
Response from Fiddler:
[HttpException]: The controller for
path
'/Services/EpicWeb-Services-LegacyDomainService.svc/binary'
was not found or does not implement
IController. at
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext
requestContext, Type controllerType)
at
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext
requestContext, String controllerName)
at
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase
httpContext) at
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext
httpContext) at
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext
httpContext) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at
System.Web.HttpApplication.ExecuteStep(IExecutionStep
step, Boolean& completedSynchronously)
Looks like all I needed was an IgnoreRoute.
First attempt was a typo.
routes.IgnoreRoute("{*allsvc}", new { allsvc = #".*\.svc(/.*)?" });