WebAPI SignalR Negotiate response different on different browsers - asp.net-web-api

The main problem about Access-Control-Allow-Origin I think. But when I configure the Web API project as defined in the given documentation, it still not working in chrome and firefox but working in IE well (it is about IE thinks localhost is not cross domain, AFAIK). I tried different ways to make it work but no result.
I put the example project to github repository. Project is very simple. There are two applications working on cross domains. It is very simple chat application like in signalr examples.
You must change the value of api host in client javascript file:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApp/Scripts/app/chat.js#L2
When you open the Chat page in mvc project, there will be two requests to api application
1- Regular ajax request (which is working fine)
2- Signalr negotiate request (cancelled)
And also I don't think browser disables the CORS because of if it disables there would not be an hit to server. So I think it is about browser but not about browser disables (something else).
Details are in repository
Readme: https://github.com/yusufuzun/WebApiSignalR/blob/master/README.md
Fiddler Results: https://github.com/yusufuzun/WebApiSignalR/blob/master/FiddlerResults
The bad part about it also is server returning 500 with this error:
System.InvalidOperationException: 'chat' Hub could not be resolved.
Which hub name is chat also.
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Hubs/ChatHub.cs#L10
You can enable CORS for Web Api in project with different ways for test purposes. Each one is giving different errors all about XMLHttpRequest Access-Control-Allow-Origin.
I commented them, so you can uncomment and make test for each one:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Global.asax.cs#L24
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L14
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L16
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Controllers/ChatController.cs#L17
So what is going on here?

After I talked with David Fowler in JabbR, he mentioned the thing about using CORS with SignalR. My signalr startup code was wrong. So after changing the startup code like in his advice it worked well.
He also mentioned SignalR and Web API are working with different CORS definitions. So enabling or disabling one doesn't affect other.
Here is the new startup code:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
});
The old one:
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
}).UseCors(CorsOptions.AllowAll);
Hope it helps to somebody out there.

Related

Azure AD in ASP.NET Core MVC web application causes CORB for JavaScript requests

Integration of Azure AD into a ASP.NET Core MVC web application causes Cross-Origin Read Blocking for requests made by JavaScript frontend to ASP.NET controllers.
I am writing an ASP.NET Core MVC application that requires users to login using a Microsoft work account. This works. I added the following code to Startup.cs:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie(options =>
{
options.LoginPath = "/Account/SignIn/";
options.AccessDeniedPath = "/Account/AccessDenied/";
});
I am also using Telerik UI widgets for the applications user interface. Because of this, there are multiple places where I use JavaScript to make requests to my ASP.NET controllers. Ex:
function onEvent(e) {
$.post("Controller/Foo", function (data) {
...
});
}
This works great when I'm running and debugging locally using IIS Express but when I deploy the application to our server running IIS I start getting warnings about Cross-Origin Read Blocking in my browsers development tools and none of my javascript functions that make requests to my ASP.NET controllers receive data.
Here is a screenshot of the warnings:
If anyone happens to know how to approach this problem I would be very grateful; I'm new to all of this and I have no idea where to start with this particular problem.
My current thinking is either I need to figure out how to handle the 'Access-Control-Allow-Origin' header in javascript or that there is something that needs to be done in Azure.
The first thing I did was enable CORS in my application but that just allows other domains to make cross-origin requests from my application, which isn't what's happening here.
If anyone comes across this issue with CORB in Chrome and dotnet core please note that in my case I was using the ResponseCache attribute. On the first non cached request it worked and subsequent ones failed with CORB error.
Once I removed the attribute the error went away.
This does not solve the issue but gives one some direction as to where the issue might be.
I did not bother with the response cache as it's no longer needed.
Below was the offending code
[ResponseCache(Duration = 15, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new[] {"key", "type", "identifier", "app"})]

Angular JS $http request does not reach the server in ie8

I'm having issues with using $http on ie8. The request does not reach the server, until I hit a refresh. Coming back to the same link still has the same problem until I hit refresh again.
The weird thing is if the web server is on LAN and the request is made to a server in LAN, it works fine. But if the webserver is hosted remotely, it does not work!
Here is the code:
Index.html
{{test}}
Controller
app.controller(
"TestController",
function( $scope, $http) {
var url = '/test/get_data';
$http.get(url).success(function(data) {
$scope.test = data;
});
}
);
I got this error: TypeError: Object doesn't support this property or methodundefined
I prepared a JSFiddle earlier but JSFiddle is broken in ie8 so I don't provide it here.
Unfortunately I don't have a remote server that I can share with you.
Edit
Previously I used an external url which gave me 'Access Denied' error in ie because of Same Origin Policy as mentioned by one answer below. But this was not my original problem. I still have the issue above when request is from the same origin
This is a cross domain request, which is not allowed in ajax because of Same Origin Policy.
There are two solutions for this
1. JSONP: It is a cross browser way to handle cross domain ajax requests using javascript callback mechanism
2. CORS: It is a HTML5 standard, it is implemented by most of the modern browsers except IE
Mongodb lab is not supporting jsonp since it has support for CORS, that is why your request is failing in IE and works in Chrome and other browsers.
As per this post they do not have any plan to support jsonp, so I don't thick there is a way to make this work in IE.
So I found the fix... Hope this helps anyone out there that experience this problem
Angular script needs to be loaded after jQuery. I didn't have this because Yii framework that I use autoloads jQuery and the angular was not included after the jQuery.
All the controller functions need to be at the end of body section (just before the closing )
Updating to angular 1.0.5 seems to fix the problem. The problem occurred in 1.0.4 with all the above tricks. I think is related to fix 791804bd

MVC3 SSL Trouble - Can't switch from HTTPS to HTTP when SSL is not required

I'm trying to get my MVC3 site to redirect from HTTPS back to HTTP when the user browses to a page where it's not required (and they aren't logged in). I Don't want to have the load of running the whole site HTTPS but it's looking like thats the way I'll have to go.
I've been having loads of trouble with remote debug and symbols, but having gone back in time to 1985 and using message box equivalents to debug with I've come to the following conclusion:
if (filterContext.ActionDescriptor
.GetCustomAttributes(typeof(RequireHttpsAttribute), true)
.Any()
)
{
return true;
}
return false;
Always returns false.
The controller def starts as:
[FilterIP(
ConfigurationKeyAllowedSingleIPs = "AllowedAdminSingleIPs",
ConfigurationKeyAllowedMaskedIPs = "AllowedAdminMaskedIPs",
ConfigurationKeyDeniedSingleIPs = "DeniedAdminSingleIPs",
ConfigurationKeyDeniedMaskedIPs = "DeniedAdminMaskedIPs"
)]
[RequireHttps]
public class AccountController : Controller
{
And it doesn't seem to work for any actions in this controller (although they do get successfully routed to SSL).
Any suggestions? I'd love to see an answer for what I perceive as my own nubery ;)
Custom NotRequreHttpsAttribute tutorial
I use the above link post to implement my custom attribute, and redirect from https to http. Hope this helps.
My problem was discovered to be related to the bindings on the server published to. We use the same server for stage and production, and the stage https bindings were not set, so whenever it was calling an https page it was resolving into our production site (which looked the same so it was hard to spot).
Once I added a binding it was all solved. My code was ok...

Ajax call getting canceled by browser

I am using the Prototype JS framework to do Ajax calls. Here is my code:
new Ajax.Request( '/myurl.php', {method: 'post', postBody: 'id='+id+'&v='+foo, onSuccess: success, onFailure: failed} );
function success(ret) {
console.log("success",ret.readyState, ret.status);
}
function failed(ret) {
console.log("failed",ret.readyState, ret.status);
}
Most of the time, this works fine and the success function is called with a status code of 200. About 5% of the time on Safari the success function is called with a status code of 0. In this case, when I look in the Network tab of the web inspector, the ajax call is listed with a status of "canceled". I can confirm with server logs, that the request never hit the server. It's as if the ajax request was immediately canceled without even trying to connect to the server. I have not found any reliable way to reproduce this, it seems to be random. I do it 20 times and it happens once.
Does anyone know what would cause the ajax call to get canceled or return a status code of 0?
The cause may be the combination of http server and browser you are using. It doesn't seems like an error of the PrototypeJS library.
Multiple sources states that keep-alive parameter of the HTTP connection seems to be broken in Safari (see here, here or here). On Apache, they recommend adding this to the configuration:
BrowserMatch "Safari" nokeepalive
(Please check the appropriate syntax in your server documentation).
If Safari handles badly HTTP persistent connections with your server, it may explain what you experiences.
If it's not too complex for you, I would try another HTTP server, there are plenty available on every OS.
We lack a bit of information to answer fully your answer, though. The server issue is a lead but there may be others. It would be nice to know if it does the same thing in other browsers (Firefox with Firebug will display this kind of information, Chrome, Opera and IE have development builtin toolboxes). Another valid question would be how often you execute this AJAX request per second (if relevant).
I know this is an old topic, but I wanted to share a solution for Safari that might save others some time. The following line really solved all problems:
BrowserMatch "^(?=.*Safari)(?=.*Macintosh)(?!.*Chrom).*" nokeepalive gzip-only-text/html
The regex makes sure only Safari on Mac is detected, and not Mobile Safari and Chrome(ium) and such. Safari for Windows is also not matched, but the keepalive problem seems to be a Mac-Safari combination only. In addition, some Safari versions do not handle gzipped css/js well.
All our symptoms of our site crashing or CSS not completley loading in different versions of Safari which caused me to nearly pull my hair out (Safari really is the new IE) have been solved for us with this Apache 'configuration hack'.

Hitting timeout using Recaptcha in ASP.NET Options

need some advice/help here.
I just started using the Recaptcha library of ASP.NET from this link
I've followed the simple guide on that page and it worked well with localhost deployment and development.
However, after I moved the same simple page with Recaptcha to my company's server to test the page out, I hit the below exception when trying to validate the recaptcha word.
The operation has timed out
I suspect it has something to do with SSL but my company's website
that I browse, isn't using https, it is just http. I have tried both
methods, having the recaptcha to set OverrideSecureMode to "true" - it
didn't work, set it to false, it didn't work as well (such as below)
<recaptcha:RecaptchaControl
ID="recaptchaControl1" runat="server"
OverrideSecureMode="True"
PublicKey="My_Public_Key"
PrivateKey="My_Private_Key"
/>
My code behind, I'm just using a simple button to invoke and display a
text which work on localhost in Visual Studio:-
if (Page.IsValid)
{
// do the stuff
}
else
// show the error message from recaptcha
What can I do to fix this issue?? Please help.
Sounds like a problem with firewall settings on your company servers. reCAPTCHA requires port 80 outbound (not inbound) to Google servers.

Resources