Here's the scenario:
I created a web api project and an mvc project, like so:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
I installed CORS support via nuget and added the EnableCorsAttribute
I ran the project and everything worked as expected (GET, PUT, and POST) across Chrome, IE, and FireFox.
I then enabled Windows Authentication in the web api project (yes, i really need win auth in the api project). In order to get this to work, I added the xhrFields arg to my jquery.ajax call:
$.ajax({
type: method,
url: serviceUrl,
data: JSON.stringify(foo),
contentType: 'application/json; charset=UTF-8',
xhrFields: {
withCredentials: true
}
}).done(function (data) {
$('#value1').text(data);
}).error(function (jqXHR, textStatus, errorThrown) {
$('#value1').text(jqXHR.responseText || textStatus);
});
In addition, I set the EnableCorsAttribute.SupportsCredentials property = true
I tested everything out. Chrome and IE worked, FireFox did not. Firefox receives a 401 in response to it's preflight (OPTIONS) request.
It seems as though FireFox is not making an attempt to authenticate with the service.
Has anyone found a solution to this problem?
I figured out a 2-part solution.
The issue is that when Firefox issues an OPTION request and is denied with a 401, it makes no further attempt to re-authenticate. This led me down a path to bypass authentication on all OPTION requests. I couldn't find much information on the subject, but I did find this:
401 response for CORS request in IIS with Windows Auth enabled
(Original page content quoted below)
Enabling NTLM Authentication (Single Sign-On) in Firefox
This HowTo will describe how to enable NTLM authentication (Single Sign-On) in Firefox.
How many of you have noticed that when you are using Internet Explorer and you browse to your companies intranet page that it will automatically authenticate you but when you use Firefox you will be prompted with a login box?
I recently, in searching for solutions to allow NTLM authentication with Apache, stumbled across how to set a preference in Firefox that will pass the NTLM authentication information to a web server. The preference is network.automatic-ntlm-auth.trusted-uris.
So how do you do it?
1) Open Firefox and type “about:config” in the address bar. (without the quotes of course)
2) In the ‘Filter’ field type the following “network.automatic-ntlm-auth.trusted-uris”
3) Double click the name of the preference that we just searched for
4) Enter the URLs of the sites you wish to pass NTLM auth info to in the form of:
http://intranet.company.com,http://email.company.lan
5) Notice that you can use a comma separated list in this field.
6) Updated: I have created VBScript that can be used to insert this information into a users prefs.js file by using group policy or standalone if for some reason you want to use it for that.
The script is available to be downloaded here.
After downloading the script you will want to extract it from the ZIP archive and then modify the line starting with strSiteList.
NOTE: This script will not perform its function if the user has Firefox open at the time the script is executed. Running the script through group policy will work without problem unless for some reason your group policy launches Firefox before the execution of this script.
You can read through the rest of the script for additional information. If you have questions, comments or concerns please let me know.
Based on that, I set Anonymous Authentication set to Enabled in the api project's settings (I still also had Windows Authentication set to Enabled).
After running the projects (mvc and api), I was prompted for credentials when issuing a CORS request. After supplying my credentials, I was able to make GET/POST/PUTS with Firefox successfully.
To eliminate the prompting of credentials in Firefox, I received a tip from Brock Allen that led me down the path of enabling NTLM authentication. I found a post here that offers instructions on how to make the appropriate settings change.
After adding 'http://localhost' to the network.negotiate-auth.trusted-uris setting, I am now able to issue CORS requests against all verbs using Firefox without prompting for credentials.
I'm currently solving this problem and the solution of enabling the Anonymous authentication was something I didn't really like.
So struggling a bit I found the right combination described in this answer.
I'm still not 100% happy, I want to avoid the code in the global asax but through the web config I didn't succeeded jet.
I hope this may help.
Related
I have a static website on an Azure web server/portal that holds our company's documentation. Recently, I've been making changes to our code that sets our cookies to ensure that they comply with the browser SameSite requirement as explained here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
I've been able to fix all my scripts that create my cookies, but while testing them today, I see that there's this cookie message that still appears in my FireFox console:
Cookie “ARRAffinity” will be soon rejected because it has the
“sameSite” attribute set to “none” or an invalid value, without the
“secure” attribute. To know more about the “sameSite“ attribute, read
https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite
This message only appears when I clear the cache from the site and load the page. Once I reload the page a second time or load any other page after that, I no longer see the message.
I believe this ARRAffinity cookie technically comes from Azure's Application Insights (AI)--or something on the Azure web server. It doesn't appear in our javascript files at all. We use AI for our analytics. Here is the code snippet that we got from Azure about two years ago. It gets injected into the header of each .htm page on our site:
var appInsights=window.appInsights||function(a){
function b(a){c[a]=function(){var b=arguments;c.queue.push(function(){c[a].apply(c,b)})}}var c={config:a},d=document,e=window;setTimeout(function(){var b=d.createElement("script");b.src=a.url||"https://az416426.vo.msecnd.net/scripts/a/ai.0.js",d.getElementsByTagName("script")[0].parentNode.appendChild(b)});try{c.cookie=d.cookie}catch(a){}c.queue=[];for(var f=["Event","Exception","Metric","PageView","Trace","Dependency"];f.length;)b("track"+f.pop());if(b("setAuthenticatedUserContext"),b("clearAuthenticatedUserContext"),b("startTrackEvent"),b("stopTrackEvent"),b("startTrackPage"),b("stopTrackPage"),b("flush"),!a.disableExceptionTracking){f="onerror",b("_"+f);var g=e[f];e[f]=function(a,b,d,e,h){var i=g&&g(a,b,d,e,h);return!0!==i&&c["_"+f](a,b,d,e,h),i}}return c
}({
instrumentationKey:"<The Key>"
});
window.appInsights=appInsights,appInsights.queue&&0===appInsights.queue.length&&appInsights.trackPageView();
(Note that <The Key> in the snippet above is actually a unique multi-character string that Azure gave us when we set up and configured the AI resource. I removed it here for privacy.)
I've since revisited the site where I got that code, but the snippet has changed to something newer:
https://learn.microsoft.com/en-us/azure/azure-monitor/app/javascript#snippet-based-setup
I'm not sure if I need to do anything to fix this.
Does ARRAffinity cookie come from some server-side script that Microsoft creates?
Do I need to do anything on my side to resolve this console message? If so, what?
ARRAffinity cookie is automatically created by Azure. You can turn it off by going to Configuration --> General Settings and then click on Off in the App Service as shown below.
As your's is a static website, i don't think this would be an issue. In fact, it is recommenced to turn ARR Affinity to Off for any Cloud Native applications.
When ARR Affinity is turned off, all the App Service instances (in a load balanced env) will be used effectively.
If ARR Affinity is turned on, all the requests for a given session will be sent to the same server irrespective of the load on it.
By default, the setting is on to to support legacy applications that needs Session stickiness.
I've been using Postman in my app development for some time and never had any issues. I typically use it with Google Chrome while I debug my ASP.NET API code.
About a month or so ago, I started having problems where Postman doesn't seem to send the cookie my site issued.
Through Fiddler, I inspect the call I'm making to my API and see that Postman is NOT sending the cookie issued by my API app. It's sending other cookies but not the one it is supposed to send -- see below:
Under "Cookies", I do see the cookie I issue i.e. .AspNetCore.mysite_cookie -- see below:
Any idea why this might be happening?
P.S. I think this issue started after I made some changes to my code to name my cookie. My API app uses social authentication and I decided to name both cookies i.e. the one I receive from Facebook/Google/LinkedIn once the user is authenticated and the one I issue to authenticated users. I call the cookie I get from social sites social_auth_cookie and the one I issue is named mysite_cookie. I think this has something to do with this issue I'm having.
The cookie in question cannot legally be sent over an HTTP connection because its secure attribute is set.
For some reason, mysite_cookie has its secure attribute set differently from social_auth_cookie, either because you are setting it in code...
var cookie = new HttpCookie("mysite_cookie", cookieValue);
cookie.Secure = true;
...or because the service is configured to automatically set it, e.g. with something like this in web.config:
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
The flag could also potentially set by a network device (e.g. an SSL offloading appliance) in a production environment. But that's not very likely in your dev environment.
I suggest you try to same code base but over an https connection. If you are working on code that affects authentication mechanisms, you really really ought to set up your development environment with SSL anyway, or else you are going to miss a lot of bugs, and you won't be able to perform any meaningful pen testing or app scanning for potential threats.
You don't need to worry about cookies if you have them on your browser.
You can use your browser cookies by installing Postman Interceptor extension (left side of "In Sync" button).
I have been running into this issue recently with ASP.NET core 2.0. ASP.NET Core 1.1 however seems to be working just fine and the cookies are getting set in Postman
From what you have describe it seems like Postman is not picking up the cookie you want, because it doesn't recognize the name of the cookie or it is still pointing to use the old cookie.
Things you can try:
Undo all the name change and see if it works( just to get to the root of issue)
Rename one cookie and see if it still works, then proceed with other.
I hope by debugging in this way it will take you to the root cause of the issue.
In my client web application, I need to authenticate with the server using ntlm protocol. While using Angular1, with the $http service get request, the browsers (chrome, edge) were doing all the 3 steps of the NTLM authentication by prompting user for username/password.
However, with Angular2, using the http service that comes with Angular2, the browser (chrome,edge) just return 401 and do not do the subsequent steps (they do not even prompt the user for credentials).
How do I make browser do the ntlm authentication for me while using Angular2 ?
Please do not suggest the ntlm javascript library.
I'm new to StackOverflow. If I haven't given sufficient info or repeated the question, sorry about that.
Thanks in Advance.
"withCredentials" needs to set true in headers to make it work. My code is working now.
let options = new RequestOptions({ headers: headers, withCredentials: true });
I don't believe the problem is with NTLM or in your coding efforts. According to Anton Bessonov, a very reputable SO community member, some modules in Angular2 are just not production-ready yet, while Angular1 is a very stable code release, and my advise is to stick with Angular1 that for the foreseeable future. Ref: angular 1 vs angular 2 for new project
What is to be done?
We have an application deployed on the Sharepoint (corporate) Server which uses the windows credentials to log into the application.
App URL format: http://testmachine:1000/sites/test/
Windows Credentials Format: user_id#domain.co.in
The objective is to perform the load/performance testing on the application (especially the log in functionality) for such n number of users.
Normally when I hit the app URL in the Firefox/IE, it pops up a window asking for credentials. I enter the credentials, browse the app and then log out. I intend to capture this in JMeter and simulate this for large number of users.
Where I’m stuck?
Now I start the JMeter proxy server, and then try the same steps as above. But when the pop up window appears, JMeter simply doesn’t record the it nor it does record anything else after the login.
What I’ve tried?
If I try the same steps after enabling “Automatically detect intranet network” in IE, then it simply auto detects my windows credentials (No credentials pop-up), logs me into the app (this is not recorded in JMeter either) and takes me to the home page. And any page thereafter I hit gets recorded in JMeter.
I’ve also tried to use the HTTP Authorization Manager using following parameters:
BaseURL : http://testmachine:1000/sites/test/
Username: DOMAIN\USER_ID
Password: i_wont_tell_you
Domain: \
Realm:
It didn't help. I am quite confused about how-to-use the above element. And not even sure whether its a right approach to get the solution to my problem.
Any help/suggestions?
P.S. I know about a tool called Badboy, but have to go for it as a last resource. Also not even sure if it records the pop windows.
And sorry if the post is verbose.
UPDATE:
I have also tried -
Username: USER_ID and Domain: my_company_domain
But this is not the actual problem. Problem is, when I try to hit the pages (automation) which I've recorded previously return success response even if I haven't used the HTTP Authorization Manager. I'm not sure what I'm missing.
OK. Finally I got what was missing.
First, I had to change the implementation of every request to HttpClient3.1
Second, it was really frustrating to see that JMeter documentation was misleading.
It says that the config file httpclient.parameters, should be edited as following:
http.authentication.preemptive$Boolean=false
But it didn't work. Changing it to true worked like a charm.
Hope this helps other people.
JMeter works at the HTTP layer so the proxy will only capture requests made over this protocol layer. It sounds to me like you have already found the right approach to use for recording by using '“Automatically detect intranet network” in IE', you can use this method to capture most requests and you will have to figure out authentication manually. How you do this depends on how your application communicates with your server to authenticate a user.
I've recently enabled Digest Authentication on an intranet website/application I am creating for my company in ASP.NET.
The reason I have done so is because Windows Authentication seemed to only work for some users, and not for others. I could not figure out why nor do I know enough about IIS to try and trace the issue. After some trial and error, I found that digest authentication seemed to give me the behaviour that I wanted. That is: allow only users with a valid account on the domain to log in to the website with their credentials.
The problem now, is that Firefox (3+) seems to ask for the user to authenticate on every HTTP request sent to the server. This does not appear to occur in Internet Explorer (6+) or Chrome.
I've tried searching for solutions but I always arrive at dead-ends. I'll find a discussion about the issue, and every posted solution leads to a dead link...or it's on Experts Exchange and I don't have access to view to solution.
The issue appears to be related (from what I've read) to the way the different browsers send their authentication headers vs how IIS interprets them. I'm not sure what I can do to change this though? One of the solutions I had found mentioned writing an ISAPI filter to fix this, but of course the link to the finished filter was broken and I have no idea how to go about making one myself.
I've tried messing with the NTLM and other auth related strings in about:config to try and force Firefox to trust my server but that doesn't seem to work either.
From a few other sources I've read, it appears that everything should work if I switch back to Windows Authentication, but then I'm back at square one where the authentication would work only for some users and not others.
A solution for either problem would work for me, but I have very little information for the Windows Authentication issue. If someone could guide me through tracing the problem I'd gladly post more information for it as well.
Here are the URLs I've found discussing what seems like the same problem. (Sorry I couldn't make them all links, it wouldn't let me post otherwise)
support.mozilla.com/tiki-view_forum_thread.php?locale=pt-BR&forumId=1&comments_parentId=346851
www.experts-exchange.com/Software/Internet_Email/Web_Browsers/Mozilla/Q_24427378.html
channel9.msdn.com/forums/TechOff/168006-Twin-bugs-in-IIS-IE-unfair-competitive-advantage-EDIT-SOLVED/
www.derkeiler.com/Newsgroups/microsoft.public.inetserver.iis.security/2006-03/msg00141.html
This is a know bug in FF. See Advanced digest authentication works from Internet Explorer however we receive multiple authentication prompts on each GET request from fire fox
IE 6 had the same bug.A potential workaround would be to re-enable "old" Digest in IIS6:
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/1d6e22ac-0215-4d12-81e9-c9262c91b797.mspx?mfr=true
Currently, if the server send an opaque directive, the IE client will return this directive value as specified in the RFC. Unfortunately, for follow-on requests from the client where the nonce count is incremented (count 2 and beyond) the opaque directive value is not sent. This then fails authentication on the server and a 401 Unauthorized is returned. The IE client now requests the username and password for the new challenge and the file is retrieved.
This requires an additional round trip and the user is prompted for credential each time.
The RFC states that the opaque must always be sent on requests from the client.
The Digest implementation that IE6 is using is not RFC compliant (http://www.ietf.org/rfc/rfc2617.txt).
3.2.2 The Authorization Request Header
The values of the opaque and algorithm fields must be those supplied
in the WWW-Authenticate response header for the entity being
requested.
3.3 Digest Operation
A client should remember the username, password, nonce, nonce count and
opaque values associated with an authentication session to use to
construct the Authorization header in future requests within that
protection space.
Because the client is required to return the value of the opaque
directive given to it by the server for the duration of a session,
the opaque data may be used to transport authentication session state
information.
-------- Edit addition -----
Windows Authentication seemed to only work for some users, and not for others.
How did it fail? Did you enable impersonation?