Need help on sharepoint 2013 Rest API with Ajax Call.
I am trying to read the list items from publishing site to the team site. Both the sites are in different site collections.
The below code is worksfine in Internet explorer and not in Google chrome.
$(document).ready(function() {
$.support.cors = true;
$.ajax({
url:"http://icon.heart.com/WorkTools/Organization/Claim/_api/web/lists/getByTitle('Claims Links')/items?$top=200",
type:"GET",
headers:{"accept":"application/json;odata=verbose"},
dataType: "json",
success: function(data){ alert("pass")}
error: function(Data){ alert ("Fail");}
});
});
The response had Http Status code 401. The error from the $.ajax request is
Failed to load resource : the server responded with a status of 401(unauthorized)
Error 2:
XML HttpRequest Cannot load No 'Access-control-Allow-Origin' header is present on the requested resource. Oringin 'url' is therefore not allowed access.
I don't have access to the servers. I need to try only with Script editor on SharePoint 2013 page.
Most likely it occurs since Chrome refuses to set a an Origin header for a CORS request. It won't even let you explicitly override the Origin header. Basically this causes the server to see Origin: null, which results in a 403 in most cases. IE/Firefox apparently has no such constraint.
As a workaround in case of SharePoint On-Premises you could set a custom header in web.config:
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
or specify explicitly domain:
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://anotherintra.contoso.com" />
</customHeaders>
using OOB scripts, it will not be fixed. the changes need to be done at server side as specified by Vadim Gremyachev. Also it might work in IE8 but in IE10 it will show you a security pop up asking for accessing data from other domain.
headers: {
"Accept": "application/json; odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
As explained in Work with __REQUESTDIGEST, some requests require to add the request digest. Even, if this is a get request and the explanation on the ms pages is for "non-GET" requests, it solved some unauthorized issues with my api SP GET calls too.
It is possible the reason IE works and Chrome does not is due to how the respective browsers handle your credentials. To provide your credentials in chrome add the following code to your $.ajax call.
xhrFields: {
withCredentials: true
},
see
Cross domain ajax call windows authentication working in chrome and not working in Firefox
Sending credentials with cross-domain posts?
Related
I'm using Cloudflare to do so. Is it necessary to add a Google Recaptcha to the login page?
Also, does Helmet interfere with Cloudflare's Bot Fight Mode?
I noticed when I refresh my every Express app page, in the browser console, there's a warning related to Cloudflare:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'. Either the 'unsafe-inline' keyword, ...
In front-end, execution of:
<script src="/cdn-cgi/scripts/.../cloudflare-static/rocket-loader.min.js" data-cf-settings="...
faces some problem, I guess (the code was added by Cloudflare).
In Helmet's official docs, i found this link that evaluates the security of your site based on the response header:
https://helmetjs.github.io/ https://csp-evaluator.withgoogle.com/
I used this code in my back-end:
`app.use(helmet.contentSecurityPolicy(
{
directives:{
scriptSrc:["'self'","https://cdnjs.cloudflare.com"]
}
}
))`
And csp-evaluator says it's all ok but:
cdnjs.cloudflare.com is known to host Angular libraries which allow to bypass this CSP
My back-end code has nothing to do with Angular.
How to solve it?
I'm trying to implement an application that uses the same Token Based Authentication mechanism demonstrated in this really awesome example by Taiseer Joudeh.
In my application I kept encountering Cors problems. In some configurations I would get a 500 error on the Preflight (OPTIONS) request for the POST to get the token or I could get the token but then get a 404 error on the preflight request for the GET request to the actual API call with the Bearer token.
One difference was that Taiseer's code was setup to host in IISExpress (or Azure) and mine is hosted on Local IIS (running on Windows 7 at the moment).
On a hunch I tried hosting his API under Local IIS and I found the exact same problem. (500 error on the preflight request for the token and it looks like the actual API will work properly)
From what I've been reading it seems like this may be some conflict between the modules and handlers in IIS and the Cors implementation in WebApi but Taiseer's implementation works when hosted in Azure so perhaps it is a difference in the version of IIS (I'm currently running under Windows 7).
How can I sort out what is causing the problem?
The root of the problem
The Token action is not hosted in a controller but is instead built in somewhere in the lower level plumbing. The only access to the mechanism is through the override method GrantResourceOwnerCredentials() in the class that extends OAuthAuthorizationServerProvider. (In our case is ApplicationOAuthProvider.cs).
GrantResourceOwnerCredentials() does have the context available but it is not called as part of the PreFlight request so you have no way to insert the appropriate PreFlight response headers for CORS.
The solution
We eventually settled on the following solution. I'm not a big fan of it because it forces these headers into every response but at least it works.
The solution was to override Application_PreSendRequestHeaders() method in Global.asax to insert the appropriate headers.
Global.asax.cs
void Application_PreSendRequestHeaders(Object sender, EventArgs e)
{
var origin = Request.Headers.Get("Origin");
var validOrigins = ConfigurationManager.AppSettings["allowedCorsOrigins"].Split(',');
if(validOrigins.Any(o => o == origin))
{
Response.Headers.Set("Access-Control-Allow-Origin", origin);
Response.Headers.Set("Access-Control-Allow-Credentials", "true");
Response.Headers.Set("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, withcredentials, Prefer");
Response.Headers.Set("Access-Control-Expose-Headers", "Claims, *");
Response.Headers.Set("Access-Control-Max-Age", "600");
Response.Headers.Set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
}
}
This requires the following web.config entries:
web.config
<configuration>
<appSettings>
<add key="allowedCorsOrigins" value="http://www.allowedsite1.net,http://localhost:22687" />
<add key="allowedCorsMethods" value="get, post, put, delete, options, batch" />
<add key="allowedCorsHeaders" value="*" />
</appSettings>
...
</configuration>
The reason for the loop to search for the valid origins is that you can't respond with a list of allowed origins...
This solved most of the problems with one exception (If I recall correctly was problems with PUT and DELETE verbs). This required removing the "ExtensionlessUrlHandler-Integrated-4.0" and re-adding it with a path and verb in the handlers section of the web.config.
web.config (2nd change)
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="" />
</handlers>
....
</system.webServer>
Useful links related CORS
Really good description of PreFlight for CORS
Excellent Sample Application using Token Auth
It is not the IdentityServer you are using but it could be the same problem. Regarding to the IdentityServer´s Github page you have to activate RAMMFAR (runAllManagedModulesForAllRequests) for your application when running under the IIS.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
I had this same issue, I did everythin as suggested by Mr. Tom hall. But still chrome reported no Access-control-allow-origin header is present.. after inspecting with fidler i realized that my request goes through a proxy server and my proxy server is handling the preflight options request..
So in "internet options" i removed the proxy server and found out that everything is working...!!!
Following the procedure in this article I disabled the ARR Affinity cookie on my Azure Web App with this header in my responses:
Arr-Disable-Session-Affinity: True
It does remove the cookie, which is very much a good thing. But, the header itself is still coming through. This header doesn't really hurt anything, but according to that same doc it shouldn't be there:
If you add the Arr-Disable-Session-Affinity header to disable the affinity cookie, ARR will not set the cookie, but it will also remove the Arr-Disable-Session-Affinity header itself, so if your process is working correctly, you will see neither.
So...how do I get it to remove the header, too?
if you have added the Arr-Disable-Session-Affinity custom header as below in your Azure Web App web.config, then it is a correct behavior you still see the Arr-Disable-Session-Affinity header with value set to true and the ARR cookie removed in your HTTP response. I think it's an incorrect statement in the reference blog you provided which stated that the Arr-Disable-Session-Affinity header will be removed.
If you want to remove that header then the cookie will present, it's mutually exclusive.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Arr-Disable-Session-Affinity" value="true" />
</customHeaders>
</httpProtocol>
The article you refer to doesn't say specifically how to add the header so I can't tell if you did it correctly. I haven't tested but according to this article you should set it in the Application_PreSendRequestHeaders:
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.Headers.Remove("X-AspNet-Version");
Response.Headers.Remove("X-AspNetMvc-Version");
Response.Headers.Add("Arr-Disable-Session-Affinity", "True");
}
I have my application working well running on VS 2013, but when I publish on IIS 8.5 CORS stops working due:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I tried this in the web.config, but still the same:
<httpprotocol>
<customheaders>
<add name="Access-Control-Allow-Origin" value="*"></add>
</customheaders>
</httpprotocol>
The error occurs when I try to authenticate:
XMLHttpRequest cannot load http://<myurl>/token
I have this configuration for OWIN, and again, Its works well running locally:
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseOAuthBearerTokens(OAuthOptions);
I solve the issue. I was getting a 500 error that Chrome does't intercept. After use Feddler I was able to see what really was going on with my request, and I did intecept the right Response Error.
Important: If you get any error at the server with CORS It will respond you as No 'Access-Control-Allow-Origin' header is present on the requested resource., I don't know why, but makes stuff difficult to trace.
Our site is not currently safe from clickjacking, so I went into the web.config and added
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="DENY" />
</customHeaders>
</httpProtocol>
</system.webServer>
This is very straight forward code. My issue is that it's just not working. The questions I have are:
Is there a way for me to see if the X-Frame-Options is in the header response? I looked for it with httpfox and got nothing, so I can't verify if the web.config is actually putting things in the header.
Why is this not working? What can I do to test or move forward?
I did try to add it in the Global.asax in the Application_Start method, but I cant seem to "hit" this method when I debug; it does not hit breakpoints.
private void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
HttpContext.Current.Response.AddHeader("x-frame-options", "DENY");
LogHelper.Info("Cost of Care Web Application Starting");
}
I would like to add that I have tried to add it straight into the head tag and I've also tried to add it in a meta tag like so
<meta http-equiv="X-Frame-Options" content="deny">
The X-Frame-Options header can be used to control whether a page can be placed in an IFRAME. Because the Framesniffing technique relies on being able to place the victim site in an IFRAME, a web application can protect itself by sending an appropriate X-Frame-Options header.
To configure IIS to add an X-Frame-Options header to all responses for a given site, follow these steps:
Open Internet Information Services (IIS) Manager.
In the Connections pane on the left side, expand the Sites folder and select the site that you want to protect.
Double-click the HTTP Response Headers icon in the feature list in the middle.
In the Actions pane on the right side, click Add.
In the dialog box that appears, type X-Frame-Options in the Name field and type SAMEORIGIN or DENY in the Value field.
Click OK to save your changes.
Since my comments answered the question here's the end result:
For some reason setting the X-Frame-Options in web.config doesn't seem to actually work even though the documentation makes it sound like it should.
An easy work around is to set the headers manually using:
Response.AddHeader("X-Frame-Options", "DENY");
If you need this set for every request with no exceptions you can add the Application_BeginRequest to Global.asax:
protected void Application_BeginRequest()
{
Response.AddHeader("X-Frame-Options", "DENY");
}
The answer of siva.k does not work in connection with MVC5 as the header is generated twice here. The following code should work:
protected void Application_Start()
{
// MVC5 generates the "X-Frame-Options SAMEORIGIN" header by default, the following line disables the default behaviour
System.Web.Helpers.AntiForgeryConfig.SuppressXFrameOptionsHeader = true;
}
protected void Application_BeginRequest()
{
Response.AddHeader("X-Frame-Options", "DENY");
}
The SuppressXFrameOptionsHeader flag was mentioned here: https://stackoverflow.com/a/20262211/3936440
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="default-src: https:; frame-ancestors 'self' X-Frame-Options: SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
Your web.config entry needs to be under content security policy to make use of current coding not previously depreciated. The value under content security policy of value="default-src: https: is unique to your website.
The content that matters is what comes after 'value="default-src: https:' but most importantly is contained within Content Security Policy.
Here is another thing to consider:
If you have a separate back-end and UI projects (as is very common for REST based sites), make sure that you put X-Frame-Options in the UI web.config. Your API is probably allowing cross site calls so adding the header to your API project would make no sense.
I found that some file types (.asp and .htm files) were getting the X-Frame-Options header added by this mechanism and others (.js) weren't. Using the IIS Admin utility I removed the header from the application level and added it at the server level, and then all files were getting the header added.