UPDATE 1:
I have now setup IIS6 so .NET can handle calls to .css files. What do I have to do now to get it to change css files based on the referal
I do something somewhat similar for files served up by our content management system. If a http handler is turned on, it inspects the filename and path to see if the user has access to the resource. If the user does, it streams the file, otherwise it returns a 401 not authorized.
I don't see why you couldn't use a handler to jump into the pipeline for the css file, check the host name, and stream out the other css file instead (if applicable). This is straightforward in IIS7 with an integrated pipeline (you didn't specify), but is also possible in IIS6 if you let a css extension be processed by .net.
Let me know if you're interested in this approach and I'll track down some code.
Edit - Here's some code
This is not exactly what you're looking for, but you may be able to get some ideas.
NOTE: This is in IIS7 with an integrated pipeline, so in IIS6 you'll have to make a change so that .css files are handled by the .net process.
Public Class FileManagerFileAuthorization
Implements IHttpHandler
Public ReadOnly Property IsReusable As Boolean Implements System.Web.IHttpHandler.IsReusable
Get
Return True
End Get
End Property
Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
Dim req As HttpRequest = context.Request
Dim absolutePath As String = req.Path
Dim fileName As String = Path.GetFileName(absolutePath)
Dim physicalPathAndFileName As String = HttpContext.Current.Server.MapPath(absolutePath)
If File.Exists(physicalPathAndFileName) Then
' roles that the user is part of. If the user is not authenticated they are part of the public role only
Dim memberRoles As String()
If req.IsAuthenticated = False Then
memberRoles = New String() {ConfigurationManager.AppSettings("PublicRole")}
Else
Dim r As New Roles()
memberRoles = r.GetRolesForUser("")
End If
' check permissions: transmit file or deliver 401
Dim folderVirtualPath As String = Path.GetDirectoryName(absolutePath).Replace("\"c, "/"c)
Dim permissions As FileManager.FolderPermissions = FileManager.GetFolderPermissions(folderVirtualPath, memberRoles)
If permissions And FileManager.FolderPermissions.View Then
context.Response.ContentType = FileManager.GetContentType(fileName)
context.Response.AddHeader("Content-Length", New FileInfo(physicalPathAndFileName).Length.ToString())
context.Response.TransmitFile(physicalPathAndFileName)
Else
' unauthorized
context.Response.StatusCode = 401
End If
Else
' file not found
context.Response.StatusCode = 404
End If
context.Response.End()
End Sub
End Class
And the web.config - and again - this is IIS7 so you'll be using the
section under system.web section. I'm looking for any file inside the Userfiles directory, but I think you could point right to a file with this.
Note:
To allow .net to handle non-.net files in IIS, you must allow the .net process to handle the processing of these files. To do this, open IIS manager, navigate to the website, and click properties. Go to the 'home directory' tab and click 'configuration.' Add a wildcard mapping, and choose the .net dll. If you're unsure, copy the link from .ascx below.
Since it's IIS6, you won't be able to use the system.webServer section above, you'll need to add http handlers the old way. This link explains it: http://msdn.microsoft.com/en-us/library/46c5ddfy.aspx