I have an asp.NET WCF on .NET 4. This service is used to authenticate users. We are submitting a username and password and then an HTTP Header should be returned with the au
First, a little background:
You are using Access-Control-Allow-Headers
, which specifies which request headers the client is allowed to send, but you are not specifying which response headers the client is allowed to read. To allow the client to read non-simple response headers, you need to use Access-Control-Expose-Headers
. From the HTML5 Rocks CORS page:
During a CORS request, the
getResponseHeader()
method can only access simple response headers. Simple response headers are defined as follows:
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
If you want clients to be able to access other headers, you have to use the
Access-Control-Expose-Headers
header. The value of this header is a comma-delimited list of response headers you want to expose to the client.
So, given that new information, you might do:
HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "Set-Cookie");
...but there's more to it than that.
Now, the actual answer:
There's one more serious problem here: the XHR specification explictily disallows reading Set-Cookie. That's because this is functionally a cross-domain cookie-stealing attack.
Suppose domain A makes a cross-domain request to domain B. When domain B sets cookies, it's setting domain-specific cookies for domain B only. Any attempt by domain A to read domain B's cookies is a violation of the same-origin policy for cookie access.
I don't know WCF, so I'm not the sure of best way to actually do what you want, but I'd guess the solution might be to pass an auth token not through cookies (e.g., a X-WCF-Auth
header?) that domain A reads and then sets its own cookie.
The browser's security policies might block your response because you have not set:
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials","true");
If that doesn't help, try adding
xhrFields: { withCredentials: true }
to your ajax
options might also be worth a shot.