MSPSS: is there life after the helpdesk?

sharing solutions to uncommon IT problems

Posts Tagged ‘Forms authentication

SSO for a website with mixed forms and basic authentication

leave a comment »


Hello,

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 http://aspnetresources.com/tools/machineKey)

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

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:

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

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.

HTH,
Roberto.

Advertisements

Written by zantoro

March 22, 2014 at 10:10 pm

ASP.NET Ticket expiration and Forms timeout

leave a comment »


Hello,

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.

HTH,

Roberto.

Written by zantoro

July 30, 2013 at 10:03 am

Posted in IIS

Tagged with , ,