Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Application pools in IIS Security - Part 84

Suggested Videos
Part 81 - Tracing in asp.net - A real time example
Part 82 - Application pools in IIS
Part 83 - Applications isolation using application pools

In this video, we will discuss about configuring different levels of security for different application pools, with an example.

In your C:\ drive, create a folder with name "Data". Open a notepad. Copy and paste the following XML into the notepad. Save the notepad as Application1Data.xml in C:\Data folder. Open, another notepad, copy and paste the same XML. Now save the notepad as Application2Data.xml in C:\Data folder. So, at this point, you should have Application1Data.xml and Application2Data.xml in C:\Data folder.



<?xml version="1.0" encoding="utf-8" ?>
<Countries>
  <Country>
    <Id>101</Id>
    <Name>India</Name>
    <Continent>Asia</Continent>
  </Country>
  <Country>
    <Id>102</Id>
    <Name>USA</Name>
    <Continent>North America</Continent>
  </Country>
  <Country>
    <Id>103</Id>
    <Name>UK</Name>
    <Continent>Europe</Continent>
  </Country>
  <Country>
    <Id>104</Id>
    <Name>France</Name>
    <Continent>Europe</Continent>
  </Country>
</Countries>



Create an asp.net web application with name WebApplication1. Drag and drop a GridView, FileUpload, Button and a Label control on to the webform. Set Text="Load Data" for the button control. Remove the Text property of the Label control. Double click the button control to generate the event handler. At this stage, the html of webform1.aspx should be as shown below.
<div>
    <asp:GridView ID="GridView1" runat="server">
    </asp:GridView>
    <br />
    <asp:FileUpload ID="FileUpload1" runat="server" />
    <asp:Button ID="Button1" runat="server" 
    Text="Load Data" onclick="Button1_Click" />
    <br />
    <asp:Label ID="Label1" runat="server">
    </asp:Label>
</div>

WebForm1.aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Identity used = "
        System.Security.Principal.WindowsIdentity.GetCurrent().Name + "<br/>");
}

protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        DataSet ds = new DataSet();
        ds.ReadXml(FileUpload1.PostedFile.FileName);
        GridView1.DataSource = ds;
        GridView1.DataBind();
        Label1.Text = "";
    }
    else
    {
        Label1.Text = "Please select a file first";
    }
}

Create an application pool with name Application1Pool, and associate WebApplication1, with this pool. We have discussed about creating application pools and associating web applications to an application pool in Part 82 and Part 83.

Create another asp.net web application with name WebApplication2. Copy and paste the HTML and code of WebForm1 from WebApplication1. Create an application pool with name Application2Pool, and associate WebApplication2, with this pool.

Run WebApplication1, and select Application1Data.xml from C:\Data folder, and click on "Load Data" button. The data should load fine. Now, select Application2Data.xml from C:\Data folder, and click on "Load Data" button. The data should load fine, from Application2Data.xml file as well. Test the same, with WebApplication2.

At this point, both WebApplication1 and WebApplication2, are able to read from Application1Data.xml and Application2Data.xml files. The idea is, we want to allow, WebApplication1 to be able to access only Application1Data.xml and not Application2Data.xml. Along the same lines, WebApplication2 should be able to access only Application2Data.xml and not Application1Data.xml

The applications are deployed to different application pools. WebApplication1 is deployed to Application1Pool, and WebApplication2 to Application2Pool. So, WebApplication1 is executed using Application1Pool identity - IIS APPPOOL\Application1Pool, and WebApplication2 with Application2Pool identity - IIS APPPOOL\Application2Pool.

At this stage, all we have to do is, set the file permissions accordingly for the application pool identities. 

Deny access to file Application1Data.xml for IIS APPPOOL\Application2Pool identity
1. In C:\Data, right click on Application1Data.xml and select "Properties"
2. Click on the "Security" tab.
3. Click "Edit" button
4. Now click "Add"
5. Click on "Locations" button and select your "computer name" and click OK
6. In the "Enter the object names to select", text box, type IIS APPPOOL\Application2Pool and click "Check Names" button.
7. Click OK
8. In the permissions list, select "Full Control" under "Deny" and click OK.

Along the same lines, Deny access to file Application2Data.xml for  IIS APPPOOL\Application1Pool identity.

With these changes in place now, WebApplication1 should only be able to access Application1Data.xml and WebApplication2, only  Application2Data.xml. Instead of showing the "Yellow screen of death", user friendly error message can be displayed in the label control by catching the security exception as shown below.
protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            DataSet ds = new DataSet();
            ds.ReadXml(FileUpload1.PostedFile.FileName);
            GridView1.DataSource = ds;
            GridView1.DataBind();
            Label1.Text = "";
        }
        catch (System.UnauthorizedAccessException)
        {
            Label1.Text = "You do not have access to this file";
        }
        catch (Exception)
        {
            Label1.Text = "An unexpected error has occured, please contact administrator";
        }
    }
    else
    {
        Label1.Text = "Please select a file first";
    }
}

3 comments:

  1. looks like the xml file should be in project folder so that we can access it using server.mappath().The FileName property just gives the file name not the fully qualified path.

    ReplyDelete
  2. ds.ReadXml(FileUpload1.PostedFile.FileName);
    GridView1.DataSource = ds;
    GridView1.DataBind();
    Fail in the last line cause FileUpload1.PostedFile.FileName NOT return full path

    ReplyDelete
  3. 1) I think here Kudvenkat uses FileUpload as file picker (openFileDialog in WinForms).

    2) This code doesn't work in VisualStudio 2019 in Chrome. I changed it . Instead of using ds.ReadXml(FileUpload1.PostedFile.FileName) I use ds.ReadXml(FileUpload1.PostedFile.InputStream); and it works.

    ReplyDelete

It would be great if you can help share these free resources