IE7 & 8 Cause Excel to Prompt for Credentials - asp.net-mvc

I have an ASP.NET MVC3 website with custom authentication (i.e. <authentication mode="None" />). It's hosted on IIS with only Anonymous Auth enabled to support some SSO work we're doing. That's just to say that requesting a plain old file from /Content typically "just works", e.g. https://oursite.com/Content/ourlogo.jpg opens in the browser window as expected without providing credentials.
Having a problem with CSV files in IE7 and 8, however. I've placed the [im]pertinent CSV in /Content/Documents/hello.csv and linked to it normally. When the user clicks the link and chooses "Open", as opposed to "Save", it should open smoothly with Excel. However, it appears that Excel is making additional requests for authentication, and the user gets prompted for username/password. Of course, they don't have those credentials to give, and IIS doesn't want them anyway. If the user cancels out the prompt, they'll get it one more time, and after a second cancel, the CSV opens in Excel as desired.
Really want to get rid of those prompts.
The problem in production behaves the same on my dev machine running ASP.NET Dev Server, so it's probably not a problem with HTTPS or something we configured on IIS. Did a test on an empty MVC site, putting the file in the same relative location. This works correctly. Kind of leaves me thinking there's a problem in our code, but I'm at a loss to what it might be.
Would love any thoughts, as I'm about out of ideas.

The solution in our case was to deny the HTTP verbs OPTIONS, HEAD and PROPFIND for the directory hosting the CSV in IIS. Apparently Excel is making these calls as part of WebDAV.

Related

The required anti-forgery cookie "__RequestVerificationToken" is not present only in Google Chrome

I have an existing website and suddenly some days ago I can't use Google Chrome anymore for developing. When I use a standard edit and create page, I get the above error. But i'm not getting it in Internet Explorer. I use Windows 10 (all updates installed) and VS2013 with Update 4. The project is the latest MVC version. I even checked the web.config but nothing is changed. I deleted all history, cookies, passwords etc.
Anyone any idea?
I had the same problem. For me the solution was to both clear my browser cookies and to disable Adblock. Other addons may have the same effect. I believe the problem is limited to the Visual Studio / Chrome development environment and will not occur in production regardless of whether the end user has Adblock enabled or not.
Do you have a
<httpCookies requireSSL="true" />
in your Web.config? Change that to false. Then in your transforms files (Web.Prod.config, and other environments that have SSL):
<httpCookies requireSSL="true" xdt:Transform="SetAttributes" />
I'm also having the same issue in recent weeks, but it's also extending cross-browser after originating from Chrome. What's even stranger is that it still works flawlessly with the identical project on a different machine using all browsers.
I have gone so far as to uninstall all extensions, delete all cookies / data, sign out of Chrome completely and re-install it. Problem still persists.
On deployment to Azure websites the problem isn't present on any platform. My current work-around is to Ctrl-F [ValidateAntiForgeryToken] and comment out every occurrence, and re-enable it upon deployment. Annoying, but it works.
This was happening to me in Chrome, and seemed related to using the 'remember me' checkbox on login forms, and closing then re-opening the browser. The token was present on inspecting page source, but was reported as being not present during debugging sessions in visual studio. By clearing the browser cache and not checking the 'remember me' box I did not get the problem - but I don't fully understand why!!
My steps to reproduce the bug in Chrome:
Sign in to your MVC web application, clicking on 'remember me' to make it checked
Close browser
Open browser to your current retained session
Try to sign out - error happens here.
Anyway, the following solution worked for me. Inside your MVC view form, try replacing this:
#Html.AntiForgeryToken()
with:
ViewContext.Writer.Write(Html.AntiForgeryToken().ToHtmlString());
Are you on cloud platform ? chrome emits cookies from cloud domains hence the only way to do it is to map another named domain to your cloud web site
This is probably because browsers like Chrome use the Public Suffix List(https://publicsuffix.org/list/effective_tld_names.dat) to restrict certain cookies. If the domain suffix set on the cookie is shared publicly then the browser may block such a cookie in order to prevent itself from sending "unauthorized" data to other servers running on the same domain.

Static images and CSS not showing (401) but bundled css and js do

We just deployed an ASP.NET MVC 4 webapp in production and are experimenting a strange behavior : the app works but images are not showing and part of the CSS is not loading.
When analyzing the HTTP requests, I can see that :
requests to images (*.png) fail with a 401 status code
requests to css files fail with a 401 status code
requests to bundled resources (*.js / *.css) are successful.
The application has worked properly in our Dev/Integration/Staging and Pre-Prod environment so I expect it to be some IIS configuration trick ....
We have already checked that :
only anonymous authentication is enabled in IIS
the IIS Pool user has Read access to the resources
I should add that some old HTTP modules are also configured (they take care of redirecting the user to some login page if he is not authenticated ...)
(I don't know whether this is relevant, but the app fails with HTTP status 401 when accessing its root Url (virtual directory) without the trailing slash ... i.e. https://{the domain}/{WebApp Name} fails but https://{the domain}/{WebApp Name}/ works fine)
Any clue about what might be going on ?
Thanks !
I was able to fix it by..
Navigating to folder that has css files in IIS
Double click "Authentication" icon on "Features View"
Right click Anonymous Authentation as shown in the pic and select Edit
Select "Application pool identity" option as shown in the pic
Restart the website
I could finally figure it out ...
Anonymous authentication was enabled (and using default config implying that the user seen by the code is the user IUSR).
The files for the web app were not stored locally where IIS is installed, but on some sort of network shared drive ....
In that place, IUSR had no read permissions, and could therefore not read the static resources.
I had to change the default "pass-though authentication", specifying that local execution is not done as the "authenticated users" (IUSR in that case).
In the WebApp Basic Settings in IIS, do not use "pass-throuh" authentication, use "Connect as"
HTTP 401: Not authorized
What this means is that your images and css files are in a folder which requires authorization, and the web site user is not authorized to see them.
You can use:
List item web.config location elements
or create specific web.config for the css and images folders, and allow anonymous access
Setting authorization rules for a particular page or folder in web.config
Struggled with this as well... Solved it by using #Styles.Render("Location_and_Name_of_CSS_file") inside my shared view as opposed to the HTML "link" tag
Hope this helps somebody
In my case none of the above was enough to fix the issue. After spending almost whole day on this I've found out that I also had to change my View to use #Url helper.
Before I had:
<img src="/Home/RetrieveImage" alt="" width="200" height="200">
It worked if I accessed via direct Url http://localhost/{applicationname}/Home/RetrieveImage but did not load the image on Index View as it should (error 401).
I changed it to:
img src="#Url.Action("RetrieveImage")" alt="" width="200" height="200"
and issue got resolved.
To get this working with pass-through authentication:
Set app pool identity to NetworkService user
Set Connect As to "Application user" on IIS site
Open the physical path and add read permissions for "NETWORK SERVICE and [local machine]\Users"
Although the app pool is set up to user NetworkService, local\Users also requires read access to the physical path.
You can also try running IIS as Administrator.

Ensuring an acceptable online user experience while republishing to a live site

It's pretty much known that publishing to a remote location using VS2008 is a an exercise of great patience and faith.
As long as a 'publish' begins (using VS2008, publishing an MVC site), that site might be down from the first file that is successfully transferred. The problem being that unreliable internet access, or interesting error messages () can break the site, and require restarting.
It's understood that there is little to do from the VS2008 end. The question then:
What strategy can I use to ensure that there is an acceptable user experience during the 'downtime'? (e.g. "This site is currently under maintenance...")
A lovely feature of ASP.NET/IIS is that if you place a file named app_offline.htm in the root of the web application, all requests will redirect to that file. This would include requests for images, stylesheets, scripts, etc.. so you'll need to condense all media for the page into the page itself.
In fact, while Visual Studio is in the process of publishing your web application, it will place this file in the root of the application and remove it when the publish is complete. While Visual Studio doesn't allow you to customize the contents of its app_offline.htm, you can take the application offline yourself simply by uploading that page.

Unable to get windows authentication to work through local IIS

So I've created a new ASP.NET MVC project using the intranet template. web.config contains the appropriate values (e.g. <authentication mode="windows"/>).
If I fire up the web app using the VS webserver, it all looks fine - the page shows my Windows domain and username and all. However, this works in Opera and Safari as well as IE and FF, which says to me it's not using Windows auth at all (since to the best of my knowledge this doesn't work in any browser except IE/FF).
Next step is to get it working through local IIS. I create a hosts file entry pointing www.mysite.mydomain to 127.0.0.1. So in IIS I create website with a binding to www.mysite.mydomain and enable Windows authentication and disable anonymous authentication.
I have set up IE and FF to enable Windows auth as follows:
IE
Add URL to intranet group
Ensure Windows auth is enabled in the advanced settings
FF
Put 'www.mysite.mydomain' into network.automatic-ntlm-auth.trusted-uris config setting.
But when I dial up www.mysite.mydomain in IE / FF I get a login prompt. Interestingly, even when I type in my Windows login here, it still fails and shows me the login prompt again.
We don't have active directory here but my understanding is that it should work fine with a local account.
I can't think of anything else I need to do. Any suggestions?
Edit: we've recently switched to using Active Directory and the problem remains.
Edit: when I cancel the login prompt, I get taken to an 'IIS 7.5 Detailed Error' page with the following information:
HTTP Error 401.2 - Unauthorized
You are not authorized to view this page due to invalid authentication headers.**
You have to whitelist a domain specified in the hosts file in order for windows authentication to work:
Click Start, click Run, type regedit, and then click OK.
In Registry Editor, locate the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
Right-click Parameters, click New, and then click DWORD (32-bit) Value.
Type DisableStrictNameChecking and press ENTER.
Double-click the DisableStrictNameChecking registry value and type 1 in the Value data box, click OK
In Registry Editor, locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
Right-click MSV1_0, point to New, and then click Multi-String Value.
Type BackConnectionHostNames, and then press ENTER.
Right-click BackConnectionHostNames, and then click Modify.
In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
Quit Registry Editor, and then restart the IISAdmin service.
NOTE:
The original Microsoft KB links on this answer were broken and have been removed.
This article provided the instructions for setting DisableStrictNameChecking.
I recently spent three days trying to solve the same problem and it drove me crazy. It was happening on a load-balanced setup where one of the servers was authenticating correctly while the other failed. Investigating the problem - and eventually solving it - it turned out to be unrelated to the load-balanced environment, it could happen with any server when authenticating using Windows Authentication and the server is called with a name other than the one recognized by Active Directory
1. Enable Kerberos logging
To correctly diagnose your issue, you will need to enable Kerberos logging on the machine hosting your IIS site. To do so, add the following registry entry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Add Registry Value LogLevel with ValueType REG_DWORD and value
0x1.
Once you turn on logging, then you try to authenticate, you will get errors logged in your Windows Application Log. You can ignore the error KDC_ERR_PREAUTH_REQUIRED (this is just part of the handshake) but if you get the error KDC_ERR_C_PRINCIPAL_UNKNOWN that means your AD controller doesn't recognize your server therefore you need to follow the steps below.
2. KDC_ERR_C_PRINCIPAL_UNKNOWN
if you're getting KDC_ERR_C_PRINCIPAL_UNKNOWN, that means the name "mysite.mydomain.com" is different from how the AD recognizes your machine so it's unable to provide a valid kerberos ticket. In that case, you need to register a Service Principal Name (SPN) for " 'www.mysite.mydomain" on the AD.
On your AD controller, run this command - you will need Domain Admin privilege:
Setspn -A HTTP/mysite.mydomain YOUR_MACHINE_HOSTNAME
3. Use a custom identity for your Application pool
Finally, make you Application pool use a custom account that belongs to the Active Directory instead of using NetworkService. This can be done in advanced settings of your application pool.
and .. voila.
Notes: The problem could (unlikely) be related to having multiple SPNs registered to the same machine, in that case you will need to run a command to remove duplicate SPNs, but I doubt this is the case. Also try adding a different binding to your site (that doesn't use a custom name) something like htttp://localhost:custom_port_number and see if authentication works. If it works, this is an extra indication that you're suffering from the same problem I had.
Did you try putting the domain in front of the user name?
DOMAIN\username
If you don't have a domain account, try prefixing your username with the machine name:
MYCOMPUTER\myusername
You should check to see if you have Windows Authentication installed/enabled. That may sound weird but in IIS 7 you have to install and enable the various authentication methods. Check out http://support.microsoft.com/kb/942043/ for more info, see quoted section below.
Cause 1
The Web application is configured to use Integrated Windows
authentication. However, the Windows Authentication feature is not
turned on. Or, the Integrated Windows authentication native module
section of the ApplicationHost.config file or of the Web.config file
is not valid. To resolve this problem, see Resolution 1.
Original
Usually when you try to view an asp.net web page hosted on IIS and receive a login prompt it doesn't mean your credentials weren't received or that you aren't authenticated. What it means is that the account that your website is running under doesn't have the right permissions to work with the files.
In IIS 6 and 7 you can easily change the user account that your app pool runs under. Try changing the app pool identity to an account with more access specifically designed for this. Or if you want to stick with the existing account (IUSR_? Network Service?) you can grant that account more permissions on the directory where your website is stored.
This article is specifically targeted at BizTalk but has almost no references to it and focuses on troubleshooting permissions issues with IIS and app pools: http://msdn.microsoft.com/en-us/library/aa954062.aspx
Why local IIS? Can you use local IIS Express?
If so, try this. It seems that IIS Express by default has Windows Authentication set to false.
Change
<windowsAuthentication enabled="false">
to "true" in applicationhost.config file (under 'C:\Users[Profile]\Documents\IISExpress\config' folder). This works for me.
To ensure that IIS uses Windows Authentication, I think you should try to turn of other authtentication methods. If Anonymous Authentication is enabled, Windows authentication will not work. You can also read this Microsoft Support Article which describes IE and IIS requirements in details.
I got this error when I enabled Windows authentication. I wanted to authorize the user based on Windows login and there is no login page in my application.
I got the error fixed by adding the below in my Web config file.
Under the tag system.web, I changed authentication mode="None" to
authentication mode="Forms".
Under the tag appSettings, I added add key="owin:AutomaticAppStartup" value="false"
After reading the answer of Espen Burud, I solved my problem by changing in the root's web.config:
<allow users="*" />
to
<deny users="?" />
The page that needs Windows Authentication is not in the root, but in a sub directory with its own web.config with deny users ? but that did not make Windows Authentication working. Apparently, you need to deny users in the root for that to work.
The IIS config has Anonymous Authentication enabled; that did not matter. After the above change of web.config, Windows Authentication worked.
For Dot Net Core 2.2 and running on IIS, I was having issues with 401.2 Unauthorized when I would check the Enable Windows Authentication within my application. It was a exceedingly simple test website that did basically nothing, just to try and get windows authentication to work. I finally got the auth to work, and here's what you'll need:
Within Startup ConfigureServices:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
Open the application's Properties, click Debug option on the left and make sure you check Enable Windows Authentication.
But here's the kicker that I had forgotten... Configure your system to have Windows Authentication installed on IIS. This was never setup on my machine, and regardless what I did, I would always get a 401 unauthorized error. After installing this (Win 10, IIS v10.0.18362.1) I now get a login prompt. This isn't exactly what I need at this point, but at least it's not the unauthorized error. Good luck and hopefully this helps.

Forms auth redirecting css/script includes to the login page with HTTP 302

I have some includes on a login page, a css file and a js file.
<link rel="stylesheet" type="text/css" href="../../ext/resources/css/ext-all.css" />
<script type="text/javascript" src="../../ext/bootstrap.js"></script>
the requests the browser makes for these get the 302 response. Forms Auth is seeing the request as unauthorized and redirecting them to the login page. It doesn't realise that the requests are coming from the login page in the first place.
GET http://localhost:50880/ext/resources/css/ext-all.css HTTP/1.1
HTTP/1.1 302 Found
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
I thought perhaps setting the permissions of the includes folder (ext) to everyone might help.
I had the same problem. Here's how I solved it.
In IIS7, click on your website, then double-click the Authentication button.
Click on Anonymous Authentication, then click the Edit... link on the right hand side.
Make sure the "Application pool identity" checkbox is checked.
My application pool is running under the "Network Service" user (not "ApplicationPoolIdentity"). You can choose the Identity in the Advanced Settings of your application pool in IIS. This user has been given full access to the file system for the website.
You need to exclude the css files and images from getting authenticated as following in the configuration file. Using the location tag you can exclude a single file or a directory.
<location path="<RELATIVE_PATH_OF_YOUR_RESOURCE_FILES>">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
So, here's what I did that entirely solved the issue.
First, I made the change to the web.config like everyone else said to do.
I am using Anonymous Authentication in IIS, and as stated in this issue, I went into IIS > Application Pools > Right-clicked my application pool > Edit > changed the app pool to use the Application Pool Identity.
THEN - I went to the parent folder that contains my site, went into permissions for that folder, and added the server's NETWORK SERVICE account to access the folder. That did it for me. It's because the Application Pool is running under ApplicationPoolIdentity, which is the NETWORK SERVICE account on the local machine.
Hope this helps someone!
The issue I had on this was that I had downloaded a jquery plugin from the internet and copied it into my content directory on the webserver and Windows had all the files under it blocked so that they couldn't be access properly by the webserver. Unblocking the files in Windows solved the issue.
Late answer here, but I wanted to help shed some light on this IISsue. (see what I did?)
First, I want to say that David Conlisk's answer is the sure-fire-nail-it-in-the-head-fix-it-every-time answer. But in case you're like me and have deployed many applications with Forms and Anonymous auth where the Anonymous Auth Identity is set to IUSR and all the sudden I'm seeing this problem now, then listen to how I reproduced the issue and hopefully be spared from the same plight.
My standard practice is to have my web application's AppPoolIdentity run as Network Service. Then I just go to the actual directory on disk that the virtual directory is pointing to -> right click -> Properties -> Security Tab -> Edit -> Add the Network Service User -> Grant read/write permissions.
Then I enable Anonyous Authentication on the directories that I need (js, css, etc.) The app pool identity is IUSR by default.
OK. Now all of the sudden in my dev environment, I start getting 302 forms auth redirects on all my css and js! What happened? I did an SVN switch on my web application to a different branch in source control. Ugh. It completely jacked all of my on disk permissions for every single file. The only way I've ever been able to fix it is to delete the whole web app, and do a fresh checkout and re-apply Network Service read permissions (or apply permissions on every single file... and yes I've tried removing and re-adding the permissions on the parent level folder).
So this time, I decide "hell with it. I'm running my web app as Local System. That will show the disk permissions whose boss. This has worked for me from time to time as a short term workaround." But alas, not today. I swear to you that before my eyes I am looking at two deployments of a forms auth web app with exactly the same configuration and the 302 issue is only reproducing on my dev machine. The only difference is the recent SVN switch on my machine.
As soon as I Log in and get a Forms Auth Cookie, the js and css download just fine.
Bear with me, I've just made a shocking discovery. All of the servers I have this deployed on have read permissions granted to MACHINE_NAME\Users. And my dev machine does not. Once I added that to my dev machine, I was able to download my css.
TLDR;
Moral of the story is you can keep the Anonymous Auth Identity as IUSR, but then you have to grant all users read permissions on your web app on disk.
Since this is a bad idea (for security reasons), I'm going to make it my new practice to adopt David C's answer and make the Anonymous Auth Identity run as the application pool identity.

Resources