Introduction
A web application that needed to be locked down from anyone except specific users gave me fits because it would not style or accept Javascript. Here is how I resolved the issue and made the page look better and the users happier.
Background
I was having two problems during the development of an web application.
- The formating of the log on page was not properly displaying.
- I wanted to set focus to the user name when the user first hits the page.
I understood at least one problem was related to access permission; however, did not realized until looking into issue 1 that number 2 was along the same lines. This might sound easy enough but it stumped me and Internet searching did not clearly elude to the problem. So I am creating this article to create the one stop shop for the answer.
I am using the Razor View so if you're using asp.net then you will need to make the necessary adjustments to the syntax. The concept should remain the same.
I am using Visual Studio 2010 to do my development and my step by step instruction assume you are using the same environment; however, these steps should be easy enough to transfer to other development environments.
Using the code
There are two standard files we will be working with:
- Web.Config
- LogOn.cshtml
There is a custom file I created:
- setfocus.js
The folder and names that I used were the following. (I believe this is the default)
Lets start with the setfocus.js file.
We are going to create this file in the Scripts folder. Instructions are below.
- On the Solution Explorer, with your mouse pointer hover over the Scripts folder
- Press the right mouse button or Right-Click.
- A pop up screen appears
- With your mouse pointer hover over Add
- Another pop out appears
- In that screen select New Javascript....
- A new file will be created
- Select the file it will be a bunch of numbers and rename it setfocus (the full name of the file should be setfocus.js)
setfocus.js contents
$(document).ready(function(){
$('.username').first().focus();
});
Now the LogOn.cshtml file
I made some minor tweaks to this file because I did not want the ability to register, or retrieve a password. If you want to include those options don't copy and past this code exactly. I will identify which line segments are important.
@model MemberTracker.Models.LogOnModel
@{
ViewBag.Title = "Log On";
}
<h2>Log On</h2>
<p>
Please enter your user name and password.
</p>
-->
<script type="text/javascript" src="@Url.Content("~/Scripts/setfocus.js")"></script>
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
@using (Html.BeginForm()) {
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
<!--You will need to add a class to the control so that it knows which one to focus on as you
can see from the line below we added new { @class = "username"} to the Html tag. You need to
add the @ to the class so the Razor does not pic up class code. -->
@Html.TextBoxFor(m => m.UserName, new { @class = "username" })
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<div class="editor-label">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
}
The web.config file
This is where all of the magic happens. So as I eluded to earlier the issue is that when you lock down the site to force LogOn then you are not allowing anyone to have access to folders / files on the site. This includes paths folders like Content or Scripts! Essentially you're blocking users from seeing this information. Ok so now the magic. We need to add a few blocks of code to the Web.Config file to allow people to get to the files.
First up is to give permission to the Content Folder and some Style.
We are going to add the following in the Primary web.config file. (This is the one that is in the root directory) and NOT the one in the View folder.
You should have a <system.web> section in the web.config file. Since you're reading this article, I am going to assume you have already blocked users and set the authentication method = to Forms.
Here is a snippet of what you should see.
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Now let's add the code to allow users to view the style by using a little known tag called location.
This code block will get added just above the <system.web> tag shown above. Comments are included in the code.
<!---->
<location path="Content/Site.css">
<system.web>
<!---->
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
This will look like this once you put it together with the other web.config code.
<!---->
<location path="Content/Site.css">
<system.web>
<!---->
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Now Giving Access to the Javascript File
So I hate to repeat myself but this is a little repetrepetitive. We are going to create another location tag and this time the path is going to be Scripts and we are going to place it just above the other <location> tag in the web.config file.
Code: One thing to not is that in this code and path we did not set permisson to a specific file and that's ok we set it to the folder.
<location path="Scripts">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
I will save you from another code block segment so just place this above the other <location> tag in the web.config save it and you should be good to go.
Your site should now look normal or at least as normal as you want it to look at the log on and as to not frustrate users your putting the cursor where they want it with out them having to click or use the mouse.
Points of Interest
Your site should now look normal or at least as normal as you want it to look at the log on and as to not frustrate users your putting the cursor where they want it with out them having to click. Like I said in the beginning this was not very obvious and I had to do some searching around. I have one citation and that's to Scott Gu's blog which provided the information about the <location> tag.
http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx
History
Version 1