Wednesday, November 26, 2008

SharePoint ActiveX Override Module (SPAXO)

No more: "The Web site wants to run the following add-on: 'Name ActiveX Control' from 'Microsoft Corporation'. If you trust the Web site and the add-on and want to allow it to run, click here..."

SPAXO Feature

Today Randy Drisgill (a.k.a The Mossman) and I (along with the help of our fellow SharePoint911'ers) released a SharePoint Feature on CodePlex here that cures the issue that many public facing SharePoint sites have with the "The Web site wants to run the following add-on: 'Name ActiveX Control' from 'Microsoft Corporation'. If you trust the Web site and the add-on and want to allow it to run, click here..." message being displayed on pages rendered in IE.  The issue is described in the following Microsoft KB article and Randy created a solution a while back in the form of a JavaScript file that he originally blogged about here.  A few weeks ago Randy approached me about creating an Http Module that would inject the JavaScript into the response stream in order to alleviate the need to edit Master Pages and so that it could be deployed as a Feature.  As a result the SharePoint ActiveX Override Module or SPAXO for short was born.

SPAXO is a Feature that is scoped at the Web Application level and is implemented as an Http Module.  The Module will inject a script tag in one of two places depending on configuration (this is described in more detail below).  The script tag will look like the one below and by default can be found at the end of a page's source.

<script type="text/javascript" src="/_layouts/SharePoint911.SPAXO/ActiveXOverride.js"></script> 

When the Feature is activated it uses the SPWebConfigModification class (thanks to John Ross for pointing this class out) to add the Module to the httpModules section of the Web Application's web.config file.  While the SPWebConfigModification class is a little difficult to use at times and has a handful of limitations, modifying the web.config in this way ensures that all servers in the Farm are updated and that when new servers are provisioned they will have the latest configuration information available.  NOTE: The Web Application will restart automatically when the Feature is activated or deactivated because the web.config is being modified.  This should not be an issue but it is something to be aware of.

When the Feature is activated the httpModules section of the web.config file should look similar to the following:

Lines have been wrapped for readability
1  <
configuration
>
2    <system.web
>
3      <httpModules

4        <clear
/>
5         
<add name=
"SPRequest" 
6              
type="
Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, Microsoft.SharePoint, 
7                     Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
"
/> 
8          ...
 
9          <add name=
"SharePoint911.SPAXO.ActiveXOverrideModule"  
10              type="SharePoint911.SPAXO.ActiveXOverrideModule, SharePoint911.SPAXO, 
11                   
Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1d151edf9ff2fb3" /> 
12     </httpModules
13   </system.web

14 </configuration>

After the Feature is activated the Module will begin servicing requests immediately and will limit modifications to .aspx pages.  When the Http Module is initialized we register an event handler for the ReleaseRequestState event.  This event fires toward the end of the Http Pipeline and allows us to modify the response in one of two ways.  We can modify the response by appending data to the end of the stream or we can use a Filter Stream to manipulate the data as it is being written to the response.  SPAXO supports both methods and uses the append to the end method as the default.  The Filter Stream option should only be used if you notice problems with the append method or if your company's or client's policies do not allow for it. The Filter Stream option is available by making a manual configuration change (shown below) in the web.config file (we will make it configurable through Central Admin in the next release) and will inject the JavaScript tag into the HTML just before the </HEAD> tag.  If you choose to use the Filter Stream method I would encourage you to test the Feature toughly in a test environment before deploying to a production environment.  The only issue (that I am aware of) that could pose a problem is if you have pages in your environment that have the literal text </HEAD> before the true HTML end head tag.  This could happen if it is referred to in script or comments, so be aware and test before using.

In order to use the Filter Stream method mentioned above you will need to add the following configuration information into the web.config file under the appropriate nodes.  If you would like to switch back and forth between the two methods you can change the value under the setting name InjectJsToHeadSection (line 16) to False.

Lines have been wrapped for readability
1  <?
xml version=
"1.0" encoding="utf-8"?>
2  <configuration>
3    <configSections>
4      <sectionGroup name="applicationSettings" 
5                   
type="System.Configuration.ApplicationSettingsGroup, System,
6                          Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
"
>
7        <section name="SharePoint911.SPAXO.Properties.Settings"
8                
type="
System.Configuration.ClientSettingsSection, System,
9                       Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
"

10               
requirePermission="false"
/>
11     </sectionGroup>
12   </configSections>
13   <applicationSettings>
14     <SharePoint911.SPAXO.Properties.Settings>
15       <setting name="InjectJsToHeadSection" serializeAs="String">
16         <value>True</value>
17       </setting>
18     </SharePoint911.SPAXO.Properties.Settings>
19   </applicationSettings>
20 </configuration>

You may be asking yourself what impact the Module may have on server performance.  That is a great question and one you should ask.  At this point we have not compiled performance statistics but I very confident that the performance impact will be negligible when using the append method of injection (which is the default) and only slightly more than that when using the Filter Stream approach.  The reason the performance will be negligible on the append method is that Module is only making a few basic decisions before appending the data to the stream and in the case of the Filter Stream method it is only making a few more.  Both of these represent an extremely small percentage of what occurs during a typical SharePoint request.  I hope to have performance numbers soon that should back this up.

Let us know your feedback here or on CodePlex (Click Here)