This site uses cookies to deliver our services. By using this site, you acknowledge that you have read and understand our Cookie and Privacy policy. Your use of Kontext website is subject to this policy. Allow Cookies and Dismiss

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

496 views 0 comments last modified about 8 years ago Raymond Tang

C# .NET

In this page

[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控件的部署。

 

 

Related pages

Set AttachDbFilename as Relative Path in .NET Core

63 views   0 comments last modified about 2 months ago

.NET Framework, you can use |DataDirectory| to configure connection string when connecting to SQL Server database file via attach mode: AttachDbFilename=|DataDirectory|\dbname.mdf In .NET Core, you cannot directly set SQL Server Express connec...

View detail

Instantiate a Service in ConfigureServices Method in .NET Core

19 views   0 comments last modified about 2 months ago

.NET Core is built in with dependency injection. Usually method ConfigureServices in Startup class is used to register services in the container. The signature of the method looks like the following: public void ConfigureServices(IServiceC...

View detail

ASP.NET Core 2.1 Error - 'Cyrillic' is not a supported encoding name

78 views   0 comments last modified about 2 months ago

After upgrading to ASP.NET Core 2.1 (.NET Core SDK 2.1.301), you may encounter the following error about encoding: System.ArgumentException &nbsp;&nbsp; HResult=0x80070057 &nbsp;&nbsp; Message='Cyrillic' is not a supported encoding name. For information on defining a custo...

View detail

SQLite in .NET Core with Entity Framework Core

35 views   0 comments last modified about 2 months ago

SQLite is a self-contained and embedded SQL database engine. In .NET Core, Entity Framework Core provides APIs to work with SQLite. This page provides sample code to create a SQLite database using package Microsoft.EntityFrameworkCore.Sqlite . Create sample project ...

View detail

Tuples in C# (4.x, 7.0, 7.1)

138 views   0 comments last modified about 6 months ago

What is a tuple? Tuple is an ordered sequence, fixed-size, immutable and of heterogeneous objects. Tuple has been existing in other languages such as F#, Python, Perl and etc. for a long time. It was first introduced into C# from C# 4.0 and has been evolving over time. Since C# 7.1, tuple...

View detail

C# version history and core features

115 views   0 comments last modified about 6 months ago

C# is my favourite programming language and has been evolving overtime. I have been programming with many other languages but C# is always my favourite because it is simple and easy to use. Visual Studio is the most powerful tool I’ve ever used. To me, programming efficiency and peformance are th...

View detail

Add comment

Please login first to add comments.  Log in New user?  Register

Comments (0)

No comments yet.