Share via


Consuming the POST request data from EMIE for Internet Explorer 11

 

Everyone should know by now that come January 12, 2016 Microsoft will provide limited support for browser versions earlier than 11. That means Enterprise customers should really consider upgrading to version 11. The above link will show you the support versions.

I'm assuming you are well on your way to setting up your group policy objects to push out the following policies:

GPO
 

This post will focus on how to better consume what goes in text box below…. It is the policy above. If you don't see any of these options make sure you've installed the latest Internet Explorer onto the server or retrieve the templates from here.

Policy

 

Enterprise Mode for Internet Explorer will send a POST request to pretty much anything that can accept it. Most examples show a simple POST and reference to a web server. In this case you just need to look up the entry in the IIS log file and voila there you have it.

My problem is that, even with a handy tool such as the old-school Log Parser, while you can get the results, it isn't a nice format. I'd rather store the data inside of a database.

 
Follow these steps in any order you want… It is the end result that really matters….

Step One – Configure SQL Server

I'm using SQL Server 2012, but any recent one should work without a problem. You should ask your DBA if you are uncertain as to managing your SQL Server. We need to create a database, table, and stored procedure

Database Creation Script
 USE [master]
GO

/****** Object:  Database [EMReporting]    Script Date: 11/26/2014 2:54:09 PM ******/
CREATE DATABASE [EMReporting]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'EMReporting', 
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\EMReporting.mdf' , 
SIZE = 4096KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'EMReporting_log', 
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\EMReporting_log.ldf' , 
SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

ALTER DATABASE [EMReporting] SET COMPATIBILITY_LEVEL = 110
GO

IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [EMReporting].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO

ALTER DATABASE [EMReporting] SET ANSI_NULL_DEFAULT OFF 
GO

ALTER DATABASE [EMReporting] SET ANSI_NULLS OFF 
GO

ALTER DATABASE [EMReporting] SET ANSI_PADDING OFF 
GO

ALTER DATABASE [EMReporting] SET ANSI_WARNINGS OFF 
GO

ALTER DATABASE [EMReporting] SET ARITHABORT OFF 
GO

ALTER DATABASE [EMReporting] SET AUTO_CLOSE OFF 
GO

ALTER DATABASE [EMReporting] SET AUTO_CREATE_STATISTICS ON 
GO

ALTER DATABASE [EMReporting] SET AUTO_SHRINK OFF 
GO

ALTER DATABASE [EMReporting] SET AUTO_UPDATE_STATISTICS ON 
GO

ALTER DATABASE [EMReporting] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO

ALTER DATABASE [EMReporting] SET CURSOR_DEFAULT  GLOBAL 
GO

ALTER DATABASE [EMReporting] SET CONCAT_NULL_YIELDS_NULL OFF 
GO

ALTER DATABASE [EMReporting] SET NUMERIC_ROUNDABORT OFF 
GO

ALTER DATABASE [EMReporting] SET QUOTED_IDENTIFIER OFF 
GO

ALTER DATABASE [EMReporting] SET RECURSIVE_TRIGGERS OFF 
GO

ALTER DATABASE [EMReporting] SET  DISABLE_BROKER 
GO

ALTER DATABASE [EMReporting] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO

ALTER DATABASE [EMReporting] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO

ALTER DATABASE [EMReporting] SET TRUSTWORTHY OFF 
GO

ALTER DATABASE [EMReporting] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO

ALTER DATABASE [EMReporting] SET PARAMETERIZATION SIMPLE 
GO

ALTER DATABASE [EMReporting] SET READ_COMMITTED_SNAPSHOT OFF 
GO

ALTER DATABASE [EMReporting] SET HONOR_BROKER_PRIORITY OFF 
GO

ALTER DATABASE [EMReporting] SET RECOVERY FULL 
GO

ALTER DATABASE [EMReporting] SET  MULTI_USER 
GO

ALTER DATABASE [EMReporting] SET PAGE_VERIFY CHECKSUM  
GO

ALTER DATABASE [EMReporting] SET DB_CHAINING OFF 
GO

ALTER DATABASE [EMReporting] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) 
GO

ALTER DATABASE [EMReporting] SET TARGET_RECOVERY_TIME = 0 SECONDS 
GO

ALTER DATABASE [EMReporting] SET  READ_WRITE 
GO
Table Creation Script
 USE [EMReporting]
GO

/****** Object:  Table [dbo].[EMIntervention]    Script Date: 11/26/2014 2:54:52 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[EMIntervention](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [status] [nchar](3) NULL,
    [referrer] [nvarchar](max) NULL,
    [username] [nvarchar](50) NULL,
    [ipaddress] [nvarchar](50) NULL,
    [timestamp] [datetime] NULL,
 CONSTRAINT [PK_EMIntervention] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
Stored Procedure Creation Script
 USE [EMReporting]
GO

/****** Object:  StoredProcedure [dbo].[InsertIntoTable]    Script Date: 11/26/2014 2:55:17 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


CREATE PROCEDURE [dbo].[InsertIntoTable]
(
    @status nchar(3) = NULL,
    @referrer nvarchar(MAX) = NULL,
    @username nvarchar(50) = NULL,
    @ipaddress nvarchar(50) = NULL,
    @timestamp datetime
)
AS
    SET NOCOUNT OFF;
INSERT INTO [EMIntervention] ([status], [referrer], [username], [ipaddress], [timestamp]) 
VALUES (@status, @referrer, @username, @ipaddress, @timestamp);
GO

Step Two – Configure IIS and push below code to web server

IIS Configuration

You should be able to get away with using mostly default settings when you create a new web site. Just ensure these key three things:

1) Disable all authentication (Features View of the site) except for Windows Authentication. Keep it enabled.

2) Ensure the application pool supports the 4. NET Framework.

3) Create firewall exception if you are using a non-default port in the binding. Above I'm pointing to port 8088.

 

Web Application

The below was written with Visual Studio 2012 (Update 4).

1) Create an empty ASP.Net Web application.

2) Add a new WebForm (mine is called Post.aspx). In the code behind, this is what I wrote inside of the partial class…

    1:  public struct DataBlock
    2:  {
    3:      public DateTime timestamp { get; set; }
    4:      public string referrer { get; set; }
    5:      public string user { get; set; }
    6:      public string ipaddress { get; set; }
    7:      public string status { get; set; }
    8:  }
    9:   
   10:  protected string GetIPAddress()
   11:  {
   12:      System.Web.HttpContext context = System.Web.HttpContext.Current;
   13:      string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
   14:   
   15:      if (!string.IsNullOrEmpty(ipAddress))
   16:      {
   17:          string[] addresses = ipAddress.Split(',');
   18:          if (addresses.Length != 0)
   19:          {
   20:              return addresses[0];
   21:          }
   22:      }
   23:   
   24:      return context.Request.ServerVariables["REMOTE_ADDR"];
   25:  }
   26:   
   27:   
   28:  protected void Page_Load(object sender, EventArgs e)
   29:  {
   30:      DataBlock datablock = new DataBlock();
   31:   
   32:      datablock.timestamp = HttpContext.Current.Timestamp;
   33:      datablock.referrer = Request.Form["URL"];
   34:      datablock.status = Request.Form["EnterpriseMode"];
   35:      datablock.user = Request.LogonUserIdentity.Name;
   36:      datablock.ipaddress = GetIPAddress();
   37:   
   38:      WriteToSqlServer(datablock);
   39:  }
   40:   
   41:  private void WriteToSqlServer(DataBlock datablock)
   42:  {
   43:      string strConnection = ConfigurationManager.ConnectionStrings["EMReportingConnectionString"].ConnectionString;
   44:      using (SqlConnection connection = new SqlConnection(strConnection))
   45:      {
   46:          connection.Open();
   47:          using (SqlCommand command = new SqlCommand())
   48:          {
   49:              command.Connection = connection;
   50:              command.CommandType = CommandType.StoredProcedure;
   51:              command.CommandText = "dbo.InsertIntoTable";
   52:              command.Parameters.AddWithValue("@status", datablock.status);
   53:              command.Parameters.AddWithValue("@referrer", datablock.referrer);
   54:              command.Parameters.AddWithValue("@username", datablock.user);
   55:              command.Parameters.AddWithValue("@ipaddress", datablock.ipaddress);
   56:              command.Parameters.AddWithValue("@timestamp", datablock.timestamp);
   57:              command.ExecuteNonQuery();
   58:          }
   59:      }
   60:  }

Here's a breakdown:

Lines 1-8: I'm defining a structure for easier usage when passing as a parameter.

Line 10-25: It is a helper function that returns the client IP. You may want to modify it as you see fit. I'm not using a load balancer in my testing.

Lines 28-39: It is retrieving information about the request such as IP Address, timestamp, the user name (this is why we have windows authentication enabled) and two interesting ones: URL and EnterpriseMode. You can see these two items in the POST body. Below is a screenshot of a Fiddler Inspector called "TextView" from when a user turns off Enterprise Mode for a given site.

fiddler

This information is really useful because the IT Admin can keep track of what sites individual users enabled/disabled (On/Off) Enterprise Mode against. The idea is to ultimately consolidate these findings into the Enterprise Mode Site List. That second policy definition further up in this post (https://SERVER01:8088/sites.xml) OR fix the sites you missed during the initial inventory process.

Lines 41-60: This code calls a stored procedure that writes the data neatly to a table… It assumes you have a stored procedure called "dbo.Insert". See Step One – Configure SQL Server.

3) Make sure that your project's web.config is pointing to the database. I'm using SQL Authentication since I defined a user that has access to the particular database/table. Here is what I am using inside of my web.config file.

    1:  <configuration>
    2:      <connectionStrings>
    3:          <add name="EMReportingConnectionString" connectionString="Data Source=sqlserver01;Initial Catalog=EMReporting;user id=EMUser;Password=[EnterPasswordHere]"
    4:              providerName="System.Data.SqlClient" />
    5:      </connectionStrings>
    6:      <system.web>
    7:        <compilation debug="true" targetFramework="4.5" />
    8:        <httpRuntime targetFramework="4.5" />
    9:      </system.web>
   10:   
   11:  </configuration>

 

4. Deploy the application. I used the built in "Publish" mechanism from within Visual Studio. You just need to make sure the development and target machines have at least Web Deploy 3.5 installed.

End Result

If the code (Step Two) compiled and was deployed properly AND you've successfully created the database, table, and stored procedure (Step One) AND there is a group policy defining where to POST the end user action, you can now focus on the client.

When a client goes to a site and say it looks bad and decided to enable Enterprise Mode via Tools –> Enterprise Mode, EMIE will send a POST to your ASPX page which in turn sends the results via stored procedure into a SQL Table.

You go to the SQL Server and take a look and this is what you get:

SQL

The sample project and SQL scripts can be downloaded from here.