MSPSS: is there life after the helpdesk?

sharing solutions to uncommon IT problems

Archive for the ‘IIS’ Category

SSO for a website with mixed forms and basic authentication

leave a comment »


We have tried to achieve Single Sign-On for a while consolidating 3 of our websites into one. The challenge was that 1 website was using Forms based authentication (fed by Active Directory through Dotnetnuke), 1 with basic authentication and classic ASP and 1 is a document repository with basic authentication.

My first challenge was to enable cross-application authentication for all applications (ASP and .NET) hosted outside the DotNetNuke pool (but still in the same website).
Frankly I had never had to do this before and I was surprised by simplicity of it all:
All we need in this case is to have the same <machinekey> in the web.config of every web application.
The machinekey is the key that is used to encrypt the authentication cookie, having the same machinekey allows other applications to decrypt the same cookie and find out who the user is.
IIS by default generates the machinekey on the go, if you want to achieve SSO you will have to specify it explicitly in the web.config (you can generate the keys from many websites like

<machineKey validationKey=”yourvalidationkey” decryptionKey=”youdecryptkey” decryption=”3DES” validation=”SHA1″ />
<authentication mode=”Forms”>
<forms name=”whatever” protection=”All” timeout=”60″ cookieless=”UseCookies” />

Once I did this I could easily retrieve the username from an ASP.NET page (using User.Identity.Name).
On classic ASP (using Request.ServerVariables(“AUTH_USER”)) is also easy but I had to configure IIS to process requests coming for .asp through .NET Framework. In IIS7.5 this is easy if you use its integrated pipeline (application pool mode=integrated) but it is also possible to achieve with the classic mode.
I followed this article: Wildcard mapping
Obviously once you did all this, you will have to update your apps to retrieve the username from the variables above.

So, at this stage I was already quite happy as I had achieved SSO throughout all our web applications but still I couldn’t find a way to do the same for our document repository as it uses built in (i.e.: not adaptable) functionalities of IIS such as basic authentication coupled with NTFS security.
Then I started thinking that this could be achieved by developing my own isapi filter that would do the checking on NTFS on the user behalf.
On IIS7.5 isapi have been replaced by http handlers and http modules. What I needed was an HTTP module that would:

  • Decrypt the cookie and retrieve the user
  • Redirect to the login page if the user is not logged in
  • Check the NTFS effective permissions of the user against the file he’s trying to download
  • If he doesn’t have read rights, redirect the user to the “not authorised page”
  • If he does have read rights, let the request go (the download is actually operated under the application pool identity)

This would not only achieve SSO for the document repository but would also give the user a better experience as if he is missing rights, he is not presented with the never ending login prompts typical of basic authentication but he’s given a clear “not authorised” message.

Here is the code I’ve put together (wordpress doesn’t allow me to upload actual code files or text so I had to PDF it): ntfs_checker
You can either compile it into dll and put in the bin folder or rename it to .vb and put it in the app_code folder and add the following tags in the web.config:

<add name=”ntfs_checker” type=”ntfs_checker” />
<add key=”Domain” value=”AD_Domain_Netbios”/>
<add key=”LoginPage” value=”/login.aspx”/>
<add key=”NotAuthPage” value=”/NotAuthorized.aspx”/>

If anyone tries it out and finds new ways to improve it, please post it back.

P.S.: one little update: the application pool of the NTFS checker must run with 32-bit apps enabled or it won’t work.


Written by zantoro

March 22, 2014 at 10:10 pm

IIS6 – Classic ASP – Special characters being displayed as �

leave a comment »


I haven’t posted anything in a while maybe a bit because I got lazy and/or maybe because I’m thinking of writing a big article about my last experience in the Philippines and I can put my mind to it…

Anyway… today I fixed an unusual problem on one of our websites, it was displaying special characters (like the accented i “í” or the ©) as “�”.

I knew right away the problem was somehow due to the wrong charset being referenced in the page. Initially I thought it could be due to the hex string problem I already wrote about some time ago but I couldn’t find said string anywhere in the text.

Eventually I found out that the problem was caused by this line:
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

Removing the “; charset=utf-8” fixed the issue.



Written by zantoro

March 5, 2014 at 2:25 pm

Posted in IIS

Tagged with ,

IIS7.5: Could not load file or assembly ‘AjaxControlToolkit’ or one of its dependencies. Access is denied.

leave a comment »


I’m writing a quick post about this as the info I found on the internet were quite confusing and often superficial…

From my experience, most of the times, this error is due to some missing NTFS rights on a folder for the user that you impersonate when visiting a website (in most cases either the anonymous user or the application pool identity).

Most people tell you to click here and there, adding rights for random users… I suggest to take a more professional (and simple) approach.

  1. Download “Process monitor” (sysinternals)
  2. Add a filter to show log activity only for the PID of the W3WP.exe process running your website (e.g.: process IS 764)
  3. Reproduce the problem
  4. Stop the monitoring and search for “Denied”

You’ll find a line that says which folder is causing the error, the user and the kind of access it requires.

Add that right, no more no less to the folder reported and you should be good to go…



Written by zantoro

October 9, 2013 at 4:42 pm

Posted in IIS

Tagged with , ,

ASP.NET Ticket expiration and Forms timeout

leave a comment »


we have an internally developed .NET 2.0 CMS that makes heavy use of Forms authentication.

On a customer’s site we experienced random downtimes (~ twice per month) due to a maxed out pool of connections to the Database server (SQL Server).

Error : System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached

When I looked at the IIS logs of the website, around the time of the crash, I could see repeated anonymous calls to pages from the same IP.

Initially I thought of a DoS attack, but then I realised that the same IP, not too long before had been used by an authenticated user.

Then I thought, the user must have a virus, but then I comparing it the other downtimes I saw that the users were different each time.

This is when I realized that out application event log was filled with this info message:

Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired.

At this stage I started researching how forms authentication times out on .NET 2.0.

As far as I can see, there are 2 timeouts: the ticket expiration and the Forms timeout.

What happened in our site is that the ticket was set to 60 minutes and the Forms timeout (web.config) to 90.

If a user would try to browse in the span of time between minute 61 and 89, his/her browser would start an infinite loop trying to go back to the private homepage which it could not access as the ticket was expired.

This infinite loop caused the user to exhaust the website’s Database connections.

I even managed to reproduce the problem and get the infinite loop error (HTTP 310).

There are still unanswered questions like:

– Why did the website loop instead of kicking the user out?

– Why didn’t the ticket get renewed although in the web.config it is set to slidingExpiration=”true”

For the moment the Developers and I have agreed to set ticket expiration and forms timeout to the same value and the problem seems to have stopped. I hope I’ll be able to answer those other questions soon.

One more tip: according to my research, these are the only 2 values in .NET that allows you to extend a user authentication. Our customers use these CMS as collaboration tools and often demand to have it set to several hours. We did some testing and saw no drawbacks in having both set to 600 minutes.

One more thing: I’ve also asked our developers to make the ticket expiration and application variable (web.config) so that we can tweak it without having to edit the login page.



Written by zantoro

July 30, 2013 at 10:03 am

Posted in IIS

Tagged with , ,

Dotnetnuke 7 + ActiveDirectory module: login prompt

with 3 comments


we are setting up an evolutionary prototype of Dotnetnuke which will eventually replace our current extranet portal.

I’ve setup the new, out-of-the-box DNNPro_ActiveDirectoryAuthentication module.

Everything works as expected (ie: AD users can login successfully) but often, the first time you open the website you are presented with a login prompt.


If you hit cancel, the system shows that /DesktopModules/AuthenticationServices/DNNPro_ActiveDirectory/WindowsSignin.aspx is asking for credentials.

In other words, DNN is trying to get you to automatically sign-in using your system credentials, then, when the login fails, it prompts you with a login box.

you may say: but I never asked to be logged in automatically! Neither did I and I struggled to find a reason and a solution.

In the module there’s no way to enable/disable this feature, but you can limit the automatic sign in to a range of IPs:

I simply limited the range of “allowed” IP to an unused internal ip (e.g.: and that did the trick


UPDATE: The solution I provided above was also causing a runtime error: “Index and length must refer to a location within the string. Parameter name: length”. In the end, in order to fix the problem, I had to disable auto-login altogether by commenting out the following line in the <modules> section of the web.config:

<add name=”Authentication” type=”DotNetNuke.Professional.Authentication.ActiveDirectory.HttpModules.AuthenticationModule, DotNetNuke.Professional.Authentication.ActiveDirectory” />

Written by zantoro

June 12, 2013 at 12:51 pm

Posted in DotNetNuke, IIS

Tagged with , ,

Etherpad Lite on windows – not as easy as it sounds

with 5 comments

Etherpad is a great real-time collaboration tool… and it’s free. The problem is that, like most cool open source, linux originated tools, is not that easy to implement for admins with a strong MS Windows background.

What’s difficult to understand for a windows guy is that this tool doesn’t get installed through a wizard that does everything for you but you actually have to put some thinking in it… so, after you’ve unzipped the sources in a folder you can start the actual configuration.

The first part is fairly straight forward: open the settings.json and change the config to fit your needs.

If you are planning to use this server on PROD, it is recommended to:

install nodejs (remember to add the NodeJS path to the “path” environment variable)
install mysql (even on the same server) and configure the connection in the settings.json

After the installation, when accessing the /admin section you might be presented with this error: “your json is bad and you should feel bad”…


The message is cute but it doesn’t tell us much so, if you want to fix it, you should use a JS debug console (Chrome’s version is great). The JS console won’t tell you much as the error is managed and no actual JS error is fired up but if you start debugging the code with few break points you might find out a lot more.
In my case the error was due to a bad formatting of the settings file (which is compiled in json) and in particular I had inserted a common windows path, c:\program files\app\, forgetting that in Linux originated apps, Windows paths should always have double slashes (e.g.: c:\\program files\\app\\).

Last but not least, I had to face the problem of making my etherpad app Production ready for a windows environment. I had 2 major issues:

1. Which port? I’m planning to host multiple services on the same server but using these lightweight web servers only one of them can use port 80… So I’ve decided to configure IIS8 with “Reverse Proxy” this way I could host as many services as I wanted on the same port. This blog has a great “how to”

2. Set up Etherpad as Windows NT Service: I needed a way to make sure the service was always up (even after a restart) and an easy way to allow our monitoring via WMI.
I wrote a little Wrapper Service in which not only starts and monitor the responsiveness of the service but automatically restarts it if it ever goes down. In addition to that, the processes are started in the session of the service (therefore you don’t need to leave a session open) and use the process “currentdirectory” that you can specify in the web.config file.
With this wrapper service you can actually keep multiple processes under control (and not necessarily of the same type, for example with the same service I maintain 2 etherpad and 1 qwebirc).
Obviously when a process crashes you can find all sort of info in the log file.


Written by zantoro

January 24, 2013 at 10:32 pm

Posted in IIS, Windows Server

Joomla on IIS7.5 – configuration and performances

leave a comment »


first of all I would like to spend some nice words on IIS7.5 which is probably the best web server I ever got to work with.

Every time I talk to contractors I employ to develop or update one of our websites, they frown as I mention that we have a full windows environment and start saying that IIS does not support redirections, rewrites, that performance will be impaired, that I DONT HAVE SSH…

What I always tell these people is that I currently have 5 websites PHP/MySQL running under IIS7.5 and they all perform splendidly:

  • IIS7.5 supports PHP out of the box (and the admin configuration window is slightly more user friendly than the good old php.ini)
  • IIS7.5 supports redirections, rewrites and it’s even easier to configure than your htaccess, especially thanks to a handy UI which allows you to test your regular expressions. Moreover you can automatically import rules out of your htaccess file
  • IIS7.5 has 2 levels of caching (kernel and user): you don’t have that on Apache, do you?
  • IIS7.5 allows you to have multiple worker processes serving the same website (called webgarden)… see below my benchmark so see the advantages
  • IIS7.5 allows virtual hosts for FTP sites: quite handy if, like me, you have a busy web server (what do you need SSH for now???)

… and so much more.

Now to the performances… As I said earlier I currently host 5 Joomla PHP/MySQL websites, all of them on IIS7.5 webservers.

I tune around and try different options to get the most out of both Joomla and my web server but with these CMS you better be careful as some modules do not particularly like to be cached indiscriminately.

For Joomla 2.5 in particular I did a benchmark testing of a pretty big, important website:

  • 1000 pages
  • 10000 users per day
  • 9/10 Page rank

I tested it with 100 users, clicking 5 times each on 3 different URLs (chosen randomly).

The stress tool I used is Webserver Stress tool 7 by Paessler.

The different options I used are:

  • IIS7.5 Webgarden: the possibility to have multiple processes serving the same worker process
  • Joomla System (Page) Cache
  • Joomla View Cache (conservative or progressive): by the way, this type of cache doesn’t work well with some modules

I wouldn’t use the IIS7.5 built-in caching options as they mess up Joomla modules pretty badly.

View Cache No No Yes Yes Yes No No
Type of view cache N/A N/A Progressive Progressive Conservative N/A N/A
Page Cache Yes Yes No No No No No
Worker Process (Web Garden) 1 5 5 1 5 5 1
Errors 0 0 0 0 0 0 0
Avg time per page (seconds) 1.6 0.8 11 18 16 28 36
Pros SuperFast even under heavy load – no impact on events module (see view cache) SuperFast even under heavy load – no impact on events module (see view cache) Fast and component based. Fast and component based. Fast and component based. Always up to date due to no outdated cache Always up to date due to no outdated cache
Cons The admin area is not cachedThe hit counters are not incremented (we don’t use them) The admin area is not cachedThe hit counters are not incremented (we don’t use them) It causes an issue on the events page which we could probably solve It causes an issue on the events page which we could probably solve It causes an issue on the events page which we could probably solve Fast enough if server is unused but much slower under heavy load Fast enough if server is unused but much slower under heavy load

To conclude, I see no reasons for using anything more than page cache. View cache also seems interesting but you have to test each module and disable the ones that do not support it.

The webgarden is also a nice surprise, I never use it on ASP, ASP.NET websites as web gardens mess up a little Application variables but for Joomla, I haven’t experienced any problem yet.

Written by zantoro

December 23, 2012 at 11:15 pm

Posted in IIS, Joomla

Tagged with ,

Windows 2008 R2, Vmware and Driver Locked memory

with 4 comments

we have had serious performance issues on a server for some time now.
This server is heavily used and we always assumed the problems we were having were simply due to the coexistence of 3 memory and CPU hungry applications on the same box (SQL Server, IIS and Coldfusion).
We tried everything to tweak resources so that one process would not overcome the others.
Nothing seemed to work.
One thing that always bugged us was that the physical memory would go rapidly exhausted although we had increased the memory progressively to 16Gb.
What’s even more strange is that the sum of the memory of each process was far from the “Physical Memory in use” we saw in Task Manager (or process explorer).
I also tried to limit memory usage for both Coldfusion and SQL Server to 5Gb each with no success.
Then I found this application from sysinternals (M. Russinovich rocks): RAMMap
This app gives you a detailed overview of the memory allocation and strangely I had 10Gb allocated to “Driver Locked”.
Google is my friend and I found out that this is usually due to a misconfiguration of VMware.
Apparently in VMware there are two config for each resource:
1. The Hardware configuration: the actual configuration of the VM where you define the physical resources allocated (in my case I had 16Gb for RAM).
2. The resource allocations: here you can play with the VMWare resources to limit the resources configured in point 1.
I found out that in the resource allocations tab we had limited memory to 4096Mb which means that for as much as we added memory to the VM, the available memory for that machine would be always the same and the rest would be “locked” in the vmware tools driver.
I opened that tab (you’ll find it in the VM settings) and selected unlimited and now task manager shows 13Gb of available memory.

I hope this helps,

Written by zantoro

September 15, 2012 at 2:04 pm

Change Exchange CAS internal or external HTTP URLs (EWS, OAB, Autodiscovery, RPC etc.)

leave a comment »


I recently had to change the internal address address (msExchInternalHostName) used by exchange to access autodiscovery, OAB, EWS etc. The reason why I had to do it, is that we had to change the certificate (we purchased a wildcard certificate in place of the old multi-host) as we decided to save money using the same certificate for both internal and external addresses.

While some of these are accessible from the EMC, some other can only be set using Powershell.

The problem with Powershell is that sometimes the documentation is a bit sketchy and personally I was unable to find any valid documentation on how to change: EWS, Autodiscover and RPC. Moreover I was unable to find a document that would list all the changes an admin has to apply in this case and I was afraid to leave something behind (as I did).

This is an example of the Powershell documentation for setting the Autodiscover:

I knew these info were stored somewhere in AD, I did a LDP search and found it. Change all the addresses from ADSIEDIT.msc was then simple, effective and all the settings are there in front of you in plain text.

If someone is looking for the same, see if you find it in the same place or maybe you can do a LDP searching for your current address in this attribute: msExchInternalHostName.

For me it was in (use ADSIEDIT):

DomainName/Configuration/Services/Microsoft Exchange/Name/Administrative Groups/Exchange Administrative Group/Servers/CASServerName/Protocols/HTTP

Hope this helps,


Written by zantoro

August 10, 2012 at 10:28 am

Posted in Exchange, IIS

Renewing SSL Certificate on IIS6 (1024 -> 2048 bit)

leave a comment »


today I struggled quite a bit trying to replace an expired certificate on a IIS6, I thought I’d share my findings hoping it’ll save time for someone else.

A quick recap of the basic steps to follow when installing a SSL cert on a IIS6:

  1. Create a CSR (by going in the website properties -> security -> Server Certificate -> New Cert
  2. Post the CSR to the CA and obtain a .cer in return
  3. complete the certificate request by feeding the cer file to IIS6 which will produce a certificate with pk in return

Most SSL Certification Authorities nowadays only release 2048bit certs on account of the 1028 being not safe.
If your previous certificate had a 1024 encryption you are  kind of stuck because IIS6 only lets you release CSR with same characteristics as the ones of the certificate currently installed.

At this stage you only have one choice: remove your current certificate (with obvious subsequent downtime) and process your certificate request as quickly as possible.

Things that I have tried to limit downtime and that won’t work:

  • Remove certificate -> generate CSR -> Cancel request -> set old certificate -> Make request to CA -> Make a new CSR identical to the previous = SSL Error
  • Generate CSR from another website on the same server= SSL Error

I hope this helps… if you can think of an easier way let me know

Written by zantoro

May 25, 2012 at 9:49 pm

Posted in IIS