I'm probably missing something but till now haven't figure it out.
I have a MVC application which listens on the web default port (i.e. 80), at the end of the interaction with the user, it sends an ajax post request (using jquery) to a WCF 4 REST service which listens on port 90, sadly enough, I'm not allowed to do so because of the brower same origin policy security issue.
I read that Chrome, Safari and firefox support by default the CORS protocol which allow cross domain requests.
In my server I've added to the response's headers the following: Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers and Access-Control-Max-Age.
from what I saw all the cors plugins handle microsoft xdr object and doesn't change the xhr default behavior.
Any help will be appriciated,
Thanks,
Ron
Hey stewe thanks for the reply, adding the headers to the service response didn't do the trick.
But the following did (Cors solution):
a) I was using jquery v 1.5.1 and found out that someone report a bug related to cross domain requests which was fixed in later version.
b) In the Service web config I've decalred the following:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
</customHeaders>
</httpProtocol>
This sln relevant only for browsers which support CORS protocol (i.e. not IE) for that we can use easyxdm.
Eventually, I've decided not to expose my service to the user, but through an UI.
Thanks,
Ron
Related
I am creating an API that would serve data to my frontend app. The API is on api.myapp.com and the app on www.myapp.com (same domain, just another subdomain). They communicate with AJAX requests and CORS is all set up, working fine.
But I have another app on another domain (www.myotherapp.com) which partialy uses the same data as myapp, so I was thinking of reusing the API so myotherapp could requests data from it too.
I think it is one use case of API, to be reusable, right?
But then, there is something that I may have missed, because as my API has CORS enabled with "Access-Control-Allow-Origin: www.myapp.com", it won't allow other apps to use its endpoints, right? Their AJAX requests would fail with CORS policies.
So how are public API built and configured? How should I set my API so it can serve several apps (ideally, only the ones I allow)?
Thanks for the explanations :)
There is an Origin header in the request and your API should check if this header is one of the allowed. If it is, then return it as an Access-Control-Allow-Origin header.
If the API is public, it can returns * as Access-Control-Allow-Origin header.
Scenario:
CORS is disabled. API is hosted in Azure. Why I'm allowed to post to the web api from my machine, that, that I suppose is localhost domain? Can someone let me know if I have a complete misunderstanding of what CORS does?
Thank you!
While CORS is configured on the server, it is up to the client to enforce it.
Most web browsers do enforce it, and fall back to the same origin policy if it is not enabled on the server.
If you make a request with an HTTP client like Postman, or code running in some other application, CORS is not a factor.
I want to call REST-services from my Angular-app. However, these REST-services are hosted on WLP and are part of a WAR-file developed by some company a while ago, ie. we have no source code.
I can call GET-methods without any issues from Postman, I just need to set authentication and accept headers. However, calling these GET-methods from Angular via web browsers will trigger preflight request (OPTIONS) without Authentication header prop. Seems to me that OPTIONS requests are triggered by the browsers and Angular cannot set headers for them. I confirmed OPTIONS requests need authentication by running requests via Postman with and without auth header prop.
Similar problems were discussed in other posts on stackoverflow but in such cases people had control over their server side code and could alter it to avoid authentication headers for OPTIONS request. Clearly in my case, I cannot do it.
My question is if there is a possibility to configure WLP to not ask for authentication header prop in case of OPTIONS-requests (seems to be configurable for Apache web servers and Tomcat)?
Kind regards
A.H.
Even without source, you should be able to edit web.xml and modify the security-constraints to punch a hole for OPTIONS.
I'm using signalR 0.5.3, my web application is located at localhost:1234, my hub is at localhost:5678, which means same host name and different ports. Both are on IIS 7 Express, Windows 7.
When I add this to web.config of my hub server.
<add name="Access-Control-Allow-Origin" value="*" />
The Google Chrome's console yells:
The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:1234, *'.
But when I remove that config, it yells:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
I searched all over the solution to make sure that there was nowhere to have
Response.AppendHeader("Access-Control-Allow-Origin", "*");
or
map.UseCors(CorsOptions.AllowAll);
Does anyone know why hub server keeps returning 2 orgins and how to tell it to do the right job?
Thanks in advance.
To enable cross-domain SignalR requests with SignalR 0.5.3, you should call MapHubs as follows:
RouteTable.Routes.MapHubs(new HubConfiguration() { EnableCrossDomain = true });
Manually manipulating the Access-Control-Allow-Origin header is likely to cause problems since SignalR will set the header for you if you enable cross-domain access in MapHubs.
IAppBuilder.UseCors is OWIN middleware provided by the Microsoft.Owin.Cors NuGet package. This middleware is not compatible with SignalR 0.5.3, but can be used with newer versions of SignalR which don't have the EnableCrossDomain option.
I go over some other common SignalR cross-domain pitfalls in the following answer: Cross-domain will not work with a SignalR PersistentConnection
From an MVC app, I'm sourcing an iCal subscription with authentication following the answer to this SO question:
Serving an iCalendar file in ASPNET MVC with authentication
The iCal stream is being created dynamically from events in the DB using the DDay.iCal library.
This solution works fine on the local development server: both OSX Calendar and Outlook can subscribe to and receive updates from the app.
However, on the shared server at my web host, the authentication fails for both Calendar and Outlook. That is, they both keep asking me for user & password after the (correct) ones fail.
EDIT: If I point a browser at the calendar URL it also fails authentication.
EDIT: Getting weirder—Firefox authenticates and gets the iCal file. Safari, Chrome and IE fail authentication.
If I point curl at the calendar URL with the same credentials I'm successful (i.e. I get the desired iCal file). And, of course, the same credentials can be used to login to the MVC app.
EDIT — I think I know what's going on, but I don't know how to fix it. In my OnAuthorization() I add only WWW-Authentication Basic but with Fiddler I can see that three types of authentication are offered:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Secure Calendar"
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
... etc ...
At this point only Firefox responds with Basic Authorization, which succeeds.
GET <<URL>> HTTP/1.1
...
Authorization: Basic <<encoded credentials>>
IE responds with Negotiate, which fails
GET <<URL>> HTTP/1.1
...
Authorization Negotiate <<encoded stuff>>
Who is adding the other two and how can I make it stop? Here's more detail from the server response:
HTTP/1.1 401 Unauthorized
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
WWW-Authenticate: Basic realm="Secure Calendar"
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
X-Powered-By-Plesk: PleskWin
Date: Tue, 23 Oct 2012 13:27:48 GMT
Thanks,
Eric
Ha ha, the answer lay in IIS configuration.
I asked the admins at my host to turn off the other authentications, which broke everything but the iCal feed.
Now they've turned a couple back on again and the MVC site works as well as the calendar feed with authentication... whew! Very, very big smile.
Here's the IIS configuration we ended up with:
Name Status Response Type
Anonymous Authentication Enabled
ASP.NET Impersonation Disabled
Basic Authentication Disabled HTTP 401 Challenge
Digest Authentication Disabled HTTP 401 Challenge
Forms Authentication Enabled HTTP 302 Login/Redirect
Windows Authentication Enabled HTTP 401 Challenge
I'm not sure why this works—or what else might break—but today I'm happy.
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
are used by Windows authentication. Since you finally enabled anonymous authentication, all WWW-Authenticate headers will not appear.
Easy way :
If you want this "X-Powered-By-Plesk" Header to be removed from EVERY NEWLY created domains, you can create a default web.config file within the "httpdocs" folder of the "Default Host Template".
This default website template is usually located under : "C:\inetpub\vhosts.skel\0\httpdocs".
That web.config file will be used by default when you create a new website.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By-Plesk" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
TIP 1 : You can use this method to remove any unwanted Custom header (In order to not tell too much to bad guys about your server) :
<remove name="X-Powered-By"/>
<remove name="X-Powered-By-Plesk"/>
<remove name="X-AspNet-Version"/>
<remove name="X-AspNetMvc-Version"/>
TIP 2 : If you want to remove any Dynamic header (like the famous "Server" header), you will need to operate with outboundRules :
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="StripHeader_Server" patternSyntax="Wildcard">
<match serverVariable="RESPONSE_SERVER" pattern="*"/>
<action type="Rewrite" value=""></action>
</rule>
<rule name="StripHeader_ETag">
<match serverVariable="RESPONSE_ETag" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
TIP 3 : Additionally, you can use this default web.config file to set all configuration parameters you want to use for every new website (in example : to define a list of default documents for your websites, as explained on this Plesk Help article : https://support.plesk.com/hc/en-us/articles/213364049-How-to-configure-global-default-document-settings-in-Parallels-Plesk )
As a belated answer to this, you could also handle this by creating a custom message handler.
The message handler would be inheriting from DelegatingHandler and has to be added to the HttpConfiguration its MessageHandlers
A way this could look would be the following:
public class EnsureNoAuthenticationHeaderHandler : DelegatingHandler
{
async protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken )
{
var response = await base.SendAsync( request, cancellationToken );
if ( response.StatusCode == System.Net.HttpStatusCode.Unauthorized )
{
response.Headers.Remove( "WWW-Authenticate" );
}
return response;
}
}
And then register it in the HttpConfiguration somewhat like the following
private void Register( HttpConfiguration configuration )
{
configuration.MessageHandlers.Add( new EnsureNoAuthenticationHeaderHandler() );
}
Which you would probably call from your global configuration. A message handler can also be attached to a route directly, so if you don't want it to be available everywhere, just have a looked at the linked article on MSDN for more explanation
I had the same problem.
The response included 3 WWW-Authenticate headers and only Firefox worked correctly. Chrome, Bing and IE prompted for username and password but after that they did not send the Authenticate Header to the server.
I just changed IIS Authentication settings and it was solved:
Anonymous Authentication Enabled
ASP.NET Impersonation Disabled
Basic Authentication Disabled HTTP 401 Challenge
Forms Authentication Disabled HTTP 302 Login/Redirect
Windows Authentication Disabled HTTP 401 Challenge