Response to preflight request doesn't pass access control - web-services

i'm working on anghular 4 projet , and i have a problem about http request and response from the server like :
XMLHttpRequest cannot load
http://192.168.1.110:8000/updateUser/Contacts/ebba56e9-72eb-971a-9bb6-552de74d0d69. Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:4200' is therefore not allowed
access. The response had HTTP status code 405.
i have look for this prblem and i found that i have to add header attribut from the server side , i did it and i see that the response contain this header :
HEADERS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: GET, POST, OPTIONS,PUT
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Connection: close
Content-Type: application/json
Date: 2017 May 31 13:15:48
Host: 192.168.1.110:8000
X-Debug-Token: fbb39b
X-Debug-Token-Link: http://192.168.1.110:8000/_profiler/fbb39b
X-Powered-By: PHP/5.6.30
my controller is :
/**
*
* #Get("/getMenu/{id}")
*/
public function getMenuAction($id ,Request $request){
$fr= $request->get('fr') ;
$url = $this->container->getParameter('serverUri'). wsUrl::Ws_GetMenu . $uniquecsoecid. '?fr='.$fr;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, wsUrl::ws_Headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$res = new Response();
$res->setCharset('UTF-8');
$res->headers->set('Access-Control-Allow-Method','PUT');
$res->headers->set('Access-Control-Allow-Credentials','true');
$res->headers->set('Access-Control-Allow-Origin','*');
$res->headers->set('Access-Control-Allow-Headers','auth_token');
$res->setContent($response);
return $res ;
}
for more details i'm using symfony to call another backend and return the result of this backend web services to my angular client side project .
but what is confused me is that the webservice work correctly if i try to send request from restlet or postman (chrome extension) and calling the web services from my angular is not working at all .
what is the wrong , please some help

You are getting the error due to CORS. Postman is not restricted. However, setting the header in the WebService should be enough for you to have it working from your client application.
What browser are you using? Sometimes Chrome is a bit too sensitive with localhost and CORS. If so, can you try in a different browser? And here is the tool to work around it: Chrome CORS Extension

Related

Cookie is not stored in the brower, cross domain GET request

I have a domain (say cookiebaker.com) that provides files using GET requests. Whenever a request is made the cookiebaker server adds a set-cookie header to the file response.
Here is an example header (Max-Age is set for 1 month in the future):
set-cookie: cookie_name=cookie_value; Max-Age=2592000; secure; HttpOnly; SameSite=Lax
Now when I call cookiebaker.com from a different domain (say munchies.com) I can see the set-cookie header in the GET response, but munchies.com does not store the cookie. I don't see the cookie in dev tools, and it is not uploaded in subsequent requests.
I am aware that I have to set the "withCredentials" flag to true when performing the GET request, but this didn't help in my case.
Here's my stripped down munchies.com code:
let request = new XMLHttpRequest();
request.open('GET', "https://cookieBaker.com?param=value");
request.withCredentials = true; // Tell the browser to receive cookies
request.send();
Is there anything else that could block the cookie from being stored in the browser? These are all my access Control headers included in the GET response (localhost is the "real" name of munchies.com for my testing):
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type
access-control-allow-methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
access-control-allow-origin: http://localhost
access-control-expose-headers: X-WP-Total, X-WP-TotalPages
You have explicitly set SameSite=Lax on the cookiebaker.com cookie, which will restrict it from being sent in a cross-site context, e.g. a fetch() originating from munchies.com.
For an explicit cross-site cookie, you should use SameSite=None;Secure. For more in-depth implementation detail, see https://web.dev/samesite-cookie-recipes

why is XMLHttpRequest.withCredentials necessary even for same site Ajax requests

I am trying to implement an authentication service deployed in a different HTTP server from the one serving my login page.
The following diagram depicts my setup:
On step #1 my browser makes an HTTP GET request to fetch the login page. This is provided as the HTTP response in #2. My browser renders the login page and when I click the login button I send an HTTP POST to a different server (on the same localhost). This is done in #3. The authentication server checks the login details and sends a response that sets the cookie in #4.
The ajax POST request in #3 is made using jQuery:
$.post('http://127.0.0.1:8080/auth-server/some/path/',
{username: 'foo', password: 'foo'},
someCallback);
The authentication service's response (assuming authentication was successful) has the following header:
HTTP/1.1 200
Set-Cookie: session-id=v3876gc9jf22krlun57j6ellaq;Version=1
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: origin, content-type, accept, authorization
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 21 Nov 2016 16:17:08 GMT
So the cookie (session-id) is present in the HTTP response in step #4.
Now if the user tries to login again I would like the authentication service to detect that. To test that scenario I press the login button again in order to repeat the post in #3. I would have expected the second request to contain the cookie. However the second time I press the login button, the request header in the post sent out in #3 does not contain the cookie.
What I have discovered is that for the post in #3 to contain the cookie, I have to do it like this:
$.ajax({
type: 'post',
url: 'http://127.0.0.1:8080/auth-server/some/path',
crossDomain: true,
dataType: 'text',
xhrFields: {
withCredentials: true
},
data: {
username : 'foo',
password : 'foo',
},
success: someCallback
});
Why would that be necessary? MDN states that this is only required for cross-site requests. This SO post also uses xhrFields but only in relation to a cross-domain scenario. I understand that my case is not cross-domain as both the page that serves the script is on localhost, and the page to where the ajax request is sent is on the same host. I also understand that cookie domains are not port specific. Moreover, since my cookie did not explicitly specify a domain, then the effective domain is that of the request meaning 127.0.0.1 which is identical the second time I send the POST request (#3). Finally, the HTTP reponse on #4 already includes Access-Control-Allow-Origin: * which means that the resource can be accessed by any domain in a cross-site manner.
So why did I have to use the xhrFields: {withCredentials: true} to make this work?
What I understand is that setting Access-Control-Allow-Origin: * is simply enabling cross-site requests but that in order for cookies to be sent then the xhrFields: {withCredentials: true} should be used regardless (as explained in MDN section on requests with credentials). Moreover, I understand that the request is indeed cross-site since the port number is important when deciding whether a request is cross-site or not. Whether the domain of a cookie includes ports is irrelevant. Is this understanding correct?
update
I think this is explained very clearly in this answer, so maybe this question should be deleted.
All parts of the origin must match the host(ajax target) for it to be considered same-origin. The 3 part of the origin https://sales.company.com:9443 for example includes:
protocol/scheme (https - won't match http)
hostname (sales.company.com - won't match subdomain.sales.company.com)
port (9443 - won't match 443)
see https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

PCL HttpClient response ignoring cookies without a domain

I am working on a REST-based app that connects to Office365. The app will be available on multiple platforms, so I have created a portable class library to handle all the logic, including authentication. The PCL targets Windows Phone 7.1 and onwards, and includes the Microsoft HTTP Client Libraries (NuGet), which is required for Windows Phone 7.1 apps.
The last step of the authentication for Office365 is to get a FedAuth cookie from the site, and that is where I am having a problem.
The code I use to get the cookie is:
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));
The 'host' variable is just the URL of the Office365 site, and the binarySecurityToken I got from previous requests. These things work equally well in all the apps: Whether I run the PCL code from the context of a Windows Phone 7.1 app, Windows Phone 8 app, Windows 8 app, or even a Console application, I am getting exactly the same response (see below), which contains the FedAuth cookie. This I have verified using Fiddler.
Then I try to get the cookie to reuse it on subsequent requests.
var cookieCollection = handler.CookieContainer.GetCookies(new Uri(host));
foreach (var cookie in cookieCollection)
{
if (cookie.Name.StartsWith("FedAuth"))
{
//TODO: Store the cookie.
return true;
}
}
This leads to the following result: On Windows Phone 7.1 the 'cookieCollection' variable only contains the cookie rtFa'. On the other platforms it contains all three cookies 'RpsContextCookie', 'rtFa', 'FedAuth'.
Windows Phone 7.1 differs from the other apps in that this is the only platform that actually uses the HttpClient from the NuGet package. The other platforms have a native HttpClient that is swapped in by the magic of PCL.
It seems likely that the problem is caused by the FedAuth cookie not having a domain. I have tried using .GetCookies(null), and different variations of .GetCookies(new Uri("something", UriKind.Relative)), which all result in an exception. I have also tried changing most of the properties of the HttpClientHandler without luck.
Has anyone encountered this problem, and perhaps solved it? Or just a suggestion on what I could try?
The response I get on the .PostAsync above is the same on all platforms, and according to Fiddler the raw response is:
HTTP/1.1 302 Found
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Location: /
Server: Microsoft-IIS/7.5
X-SharePointHealthScore: 0
X-AspNet-Version: 4.0.30319
Set-Cookie: RpsContextCookie=; path=/
Set-Cookie: rtFa=+13jGMMp0A0V+driESaO30ixYclFCRjEvS2jMSwXPfQcrefiJvLEExxYu7V+1JZHM6X5JWeuL70jb3/N/Q/hUTwoAiC/XLJZ1QfERi4aUt8AAVF4ekcNyMdWnj65foDwPkhaV5z8whNSZQigBFD/2Vc1xMTH0ukHbS4cbtJO5U28/4g66vgIZg7dGpNOZg2jDt+HF3GSQ4/W+T1oS9/F5e+Pbwd0p8mqPhkGjL+M7IptmkeHoIqVcS4Ps25dM6q1AniLiv/3NujYmrQjseaEYZ2aaCfc7ZHX7LygBZm8KsoGNyTYRPmC+hZ7tsDq6wfto+xVpX1scggsU0+Qty3DPWUiwy1bBy8JR0znFG0+eDt9uBOQzqfOSjVvd8WNIKUFIAAAAA==; domain=sharepoint.com; path=/; HttpOnly
Set-Cookie: FedAuth=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U1A+RmFsc2UsMGguZnxtZW1iZXJzaGlwfDEwMDMwMDAwODc5MTUwMGVAbGl2ZS5jb20sMCMuZnxtZW1iZXJzaGlwfHRtakB3aWxkY293Lm9ubWljcm9zb2Z0LmNvbSwxMzAzNDIwOTYxNDAxMTIxMzMsRmFsc2UsV2lSQjlUVTdOSTk0MUpKRWZ5d1JDNTFPYUphMVpWNkJqWWdaVGM3MU00U3lqL2VkTnF6dVJpbXdEMnpEWk9oR1lybkFsNnpWb3M4V0FBZDk1VVYrZkt5dlkwQ3dqRTlyaEhEc256bkZUeENoODU1Rm1JZmxoYVBkMTFQS2VjWnFJN0N4OUxUOHk4enZDaVNUTGNQMzR2K3NOeHk1YXBMZ2NIWDNHR3JMcG1Ic24rQzAzUkUzakNDQWhma2F3RVRQbk03R3JycVk5amJseHJmNVNhNHZxMk91NlN1cGszZnpQMUZQTzJBc1UrRXZvSDgvWTllR2Y3c2x2dStvMnVlN3hZLy9VQ1lYU1U4b3AzckZ6c2laK0wwN1NrUnZYMTZjVklUVVZJZ0x6TGIxaTJLd2lwNGp6RHgwRFdmVWF0Rk42UVFaNWhHRzMyOHRJZjI2RXo4YldnPT0saHR0cHM6Ly93aWxkY293LnNoYXJlcG9pbnQuY29tLzwvU1A+; path=/; secure; HttpOnly
SPRequestGuid: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
request-id: 5bb2689c-d7c5-c07c-4890-ee32437f15f5
SPRequestDuration: 125
SPIisLatency: 2
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.2308
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
Date: Thu, 09 Jan 2014 21:46:53 GMT
Content-Length: 118
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
I found an answer of kind here: Accessing HTTPOnly cookies from Windows Phone 8/PCL.
Reading the post I realized that I made an error above: I was not getting the 'rtFa' cookie in the Windows Phone 7.1 app, but the 'RpsContextCookie'. The cookies I couldn't access were both marked with HttpOnly.
I also realized that I don't need to access the cookies directly. Instead, I could just reuse the handler.CookieContainer. So my code now looks like this:
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var newClient = new HttpClient(handler);
var newResponse = await newClient.PostAsync(host + "/_forms/default.aspx?wa=wsignin1.0", new StringContent(binarySecurityToken));
this._cookieContainer = handler.CookieContainer;
return true;
this._cookieContainer is just a class-scoped field for storage of the cookie container. Then, once I am authenticated and I do the requests that are the actual purpose of the app, I do the following:
var handler = new HttpClientHandler(){ CookieContainer = this._cookieContainer };
var client = new HttpClient(handler);
var response = await client.GetAsync(host + "something");
So the bottom line is: I can't access the HttpOnly cookies - but I don't need to. I just reuse the cookie container, and the cookies are automatically included in the next request.
This works both in Windows Phone 7.1 apps, Windows Phone 8 apps, Console applications etc.

HTTP/1.1 500 Internal Server Error when calling Web Service from .NET Client

I'm trying to connect to a https web service (not .NET as far as I know).
I can't control the other side in any way, I just got some standards and a wsdl to operate
with it.
I have created at first the client using Add Service Reference, tried some things until I get through some problems, where one most serious was that I couldn't add the Authentication header to the message which was resulting in fail.
Added the service using old Add Web Reference and seemed more easily managed and appropriate, using a partial class and override the GetWebRequest, I added this code so I can preauthenticate with the service and add the security header, which they don't mention in the wsdl link. I know that it is not mandatory for services to tell this but it would be nice my Web Service creators fellow developers.
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding()
.GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
request.Headers["Authorization"] = "Basic" + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}
To call the service I added this code:
using (Service client = new Service()) // autogenerated Service class
{
client.EnableDecompression = true;
// Create the network credentials and assign
// them to the service credentials
NetworkCredential netCredential = new NetworkCredential("test1", "test1");
Uri uri = new Uri(client.Url);
ICredentials credentials = netCredential.GetCredential(uri, "Basic");
client.Credentials = credentials;
// Be sure to set PreAuthenticate to true or else
// authentication will not be sent.
client.PreAuthenticate = true;
// Make the web service call.
Request req = new Request { UserName = "test2", Password = "test2"; // an object created from autogenerated code
RequestResult result = client.processMessage(req); // autogenerated code
}
While testing this call and checking with fiddler my request. I see 2 calls a keep alive call with these header, nothing special.
CONNECT server:443 HTTP/1.1
Host: server
Connection: Keep-Alive
Sending 570 returning a 200 result.
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 00:05:13.743
Connection: close
And the call with the data sending 571 result 500 error:
POST /host/Service HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.5448)
Authorization: BasicdXNlcOTc3MzQyMGTDFTR4dftfrdg5 // changed this hash for security reasons
VsDebuggerCausalityData: // Removed this hash for security reasons
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: server-host-url
Content-Length: 7238
Expect: 100-continue
Accept-Encoding: gzip
Connection: Keep-Alive
The error exception in .NET client:
Error on verifying message against security policy Error code:1000
As you see the Authorization header exist. I also tried with adding a space after Basic you can see above where exactly in the overriden method, and seemed fiddler recognized it better and also decoded the username:password header.
This results into that response:
HTTP/1.1 500 Internal Server Error
Date: Sat, 21 Apr 2012 21:05:22 GMT
Server: Oracle-Application-Server-11g
X-Powered-By: Servlet/2.5 JSP/2.1
X-Cnection: close
Transfer-Encoding: chunked
Content-Type: text/xml;charset="utf-8"
Content-Language: en
X-Pad: avoid browser bug
Set-Cookie: BIGipServerpoolXoas243_254_9999=437682499.99988.0000; path=/
The strange thing I wonder first is if the first call should be preauthenticated, the handshake keep alive one? This 500 error I know that causes when authentication header is not present, but mine is. Preauthentication is what I need to know how it should happen and I guess it's not working if it should appear in the 1st message.
Another strange thing is that if I change the 2 pairs of passwords opposite, I see on fiddler that I get 3 messages, 1 with the handshake and result in 200 and "TWO" others with 401 Authorization Required.
This drives me crazy. Any help appreciated to save my soul.
Thank you!

Cookie is not getting set in HTTP request in JAXWS when it's set using context

I am trying to set cookie from client using below code snippet, I am using JAXWS RI 2.2.3.
Map<String, Object> ctxt = ((BindingProvider) portType).getRequestContext();
Map<String, List<String>> httpHeaders = new HashMap<String, List<String>>();
httpHeaders.put("Content-Encoding", Collections.singletonList("gzip"));
httpHeaders.put("Cookie", Collections.singletonList(cookie));
ctxt.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
From the SOAP log I see that Cookie is not getting set, but it's set in the context header.
Any other header is getting set except Cookie and I am not able to find out the reason.
I need to get a session from one service and set it to another service to work with it, but I am not able to do so here.
HTTP headers: {Cookie=[mysession="529fc605-8188-7f3b-21ad-92407976d5a9";], Accept-Encoding=[gzip], Content-Encoding=[gzip]}
---[HTTP request - https://10.112.83.155:443/eam/sdk/]--- Accept: text/xml, multipart/related Accept-Encoding: gzip Content-Encoding: gzip Content-Type: text/xml; charset=utf-8 [] Set-Cookie: vmware_soap_session="529fc605-8188-7f3b-21ad-92407976d5a9"; SOAPAction: "urn:internaleam/2.0" User-Agent: JAX-WS RI 2.2.3-b01-
This was a bug in JAX-WS. Bug link: JAX_WS-1044
Currently fixed in JAX-WS 2.2.7 which is not yet released.