[C#] 基于.NET开发 ActiveX 控件(二) 安全篇

365 views 0 comments posted at about 7 years ago Raymond Tang

C# .NET

[C#] 基于.NET开发 ActiveX 控件(一) 基础篇

[C#] 基于.NET开发 ActiveX 控件(二) 安全篇

[C#] 基于.NET开发 ActiveX 控件(三) 部署篇

[C#] 基于.NET开发 ActiveX 控件系列文章,转载请注明来自:http://hi.baidu.com/1987raymond

[C#] 基于.NET开发 ActiveX 控件(一) 基础篇文章中,我演示了如何在.NET中开发ActiveX控件;在演示的实例中,为了使得创建的控件能够在IE中运行,我们用到了COM Interoperability 以及IObjectSafety接口,以此声明我们的控件是脚本安全的。本文将继续阐述ActiveX控件安全性方面的话题。

1.概述

查看我们的Internet Options中的安全选项卡,在安全级别设置为Medium(受信任站点)或者Medium-High(一般性Internet站点)时,下载潜在可能非安全的内容前会进行提示,并且没有经过数字签名的ActiveX是不能被下载的。

IE通过查询ActiveX组件是否实现了IObjectSafety接口,并且返回脚本安全;或者通过查询ActiveX组件是否在注册表的Component Category Manager里表明自己实现了CATID_SafeForInitializing和CATID_SafeForScripting来判断一个ActiveX是否安全。微软的推荐做法是通过实现IObjectSafety接口。IE的检验标准即是先通过创建控件实例,判断是否实现了此接口来判断,这样存在的潜在危险是在创建控件实例的代码部分会存在不安全的内容。

在创建ActiveX控件的时候,我们应该为ActiveX进行数字签名,以便防止用户安装后我们的控件被篡改,这需要用到数字签名、数字证书方面的知识,详情参考.NET中的安全性之数字签名、数字证书、强签名程序集、反编译

此外,还有一点我们需要注意,当声明我们的ActiveX控件为脚本安全后,所有网站都可以加载此ActiveX控件,为了防止其他网站借助我们的ActiveX控件获取用户隐私数据以及其它非法行为的产生,我们必须对控件安全性声明认真对待。

2.相关参考文档

关于如何设计符合安全性规则的ActiveX控件,请参考以下文档:

MSDN Designing Secure ActiveX Controls

About IObject Safety Extensions for Internet Explorer

Building ActiveX Controls for Internet Explorer

IObjectSafety and Internet Explorer

3.创建ActiveX控件

参考 [C#] 基于.NET开发 ActiveX 控件(一) 基础篇 创建Activex控件,具体详细步骤不再赘述,相关创建信息如下:

3.1解决方案与ActiveX控件类库项目:

创建用户控件ActiveXTextBox,设置内容与基础篇中的实例一致:


3.2添加并且实现IObjectSafety接口(关于接口的声明和方法说明请参考MSDNIObjectSafety接口),并且标记ComVisible特性、GUID特性(但不要设置项目属性的Register COM Interop),最终代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace DotNetActiveX.Controls
{
    [Guid("9F369A4D-7D3A-4d75-8BDB-3DD254D711A0")]
    [ProgId("DotNetActiveX.Controls.ActiveXTextBox")]
    [ComVisible(true)]
    public partial class ActiveXTextBox : UserControl, IObjectSafety
    {
        public ActiveXTextBox()
        {
            InitializeComponent();
        }

        public string InputText
        {
            get { return this.textBoxTest.Text; }
            set { this.textBoxTest.Text = value; }
        }

        #region IObjectSafety Members

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            pdwSupportedOptions = 1;
            pdwEnabledOptions = 2;
            return 0;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            return 0;
        }
        #endregion
    }


    [ComImport]
    [GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}
3.3创建测试Web项目

修改Default.aspx内容为(红色标注部分为我们创建的控件的GUID):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>AxControl Test</title>
    <script type="text/javascript">
        function showInputText() {
            alert(myAxControlTest.InputText);
        }
    </script>
</head>
<body>
    <p>
<object id="myAxControlTest" height="22" width="220" classid="clsid:9F369A4D-7D3A-4d75-8BDB-3DD254D711A0">
</object>
<input id="ButtonTest" type="button" value="Show Input Text" onclick="showInputText()" />
    </p>
</body>
</html>

4.测试ActiveX控件与相关思考

在浏览器中打开http://localhost/ActiveXWebSite/default.aspx,我们可以看到控件并未创建成功,为红色的叉,原因是IE找不到一个ID为9F369A4D-7D3A-4d75-8BDB-3DD254D711A0的对象:


勾选项目DotNetActiveX.Controls的属性中Build生成选项卡中的Register COM Interop,然后重新生成解决方案。

使用SDK中的OLE/COM Object Viewer即可查看到在生成的时候,已经注册了对象:


Tips:在OLE/COM Object Viewer中选中对象的节点DotNetActiveX.Controls.ActiveXTextBox,然后点击此窗口工具栏中的Run RegEdit即可在注册表编辑器中查找9F369A4D-7D3A-4d75-8BDB-3DD254D711A0对应的注册表节点,按Delete键即可删除此注册的对象(删除后在Object Viewer中按F5刷新)。
刷新测试页面,即可查看到正确的效果:


在Internet选项中,设置Local Interanet站点的安全级别为Medium-High或者High,再次刷新页面,依然可以运行成功;这是因为我们已经注册此对象在我们的本地PC,同时实现了IObjectSafety接口,因而IE会直接运行此ActiveX控件。

在实际的运用中,ActiveX控件是需要用户根据自己的选择是否下载安装ActiveX控件,同时我们一般采用cab打包发布我们的ActiveX控件,这样还会出现签名、IE安全等级设置等等方面的问题,我将在下一篇文章中给大家讲解ActiveX控件的部署。

 

 

Add comment

Comments (0)

No comments yet.
In this Page