VB制作(zuò)網頁的ACTIVEX控件的安全簽名問題

天遠(yuǎn)科技  發表于:2015-07-14  分(fēn)類:VB相關(guān)  閱讀(4008)  贊同30
今天太高興了(le),解決了(le)上(shàng)海批發市(shì)場(chǎng)項目中在WEB頁面中插入ACTIVEX控件導緻IE拒絕安裝的問題.以前總認為(wèi)是需要簽名證書的問題.今天上(shàng)網查了(le)查,在CSDN的一(yī)個(gè)帖子(zǐ)裏有位網友提出了(le)"簽名證書 != 代碼安全"的概念,他說(shuō)即使有了(le)合法的簽名證書,控件可以安全下(xià)載,但(dàn)不并能(néng)很好(hǎo)(hǎo)的和IE交互,會提示"有不安全的代碼交互"類似的提示,因為(wèi)我沒有使用過第三方頒發的簽名證書,無法證實他說(shuō)的正确性,但(dàn)後面的那個(gè)提示我是碰到過的.這(zhè)位網友所指的"代碼安全性"是指控件必須繼承自一(yī)個(gè)IobjectSafety接口,IE認為(wèi)這(zhè)個(gè)控件是安全的,可以加載.

附轉于網上(shàng)一(yī)篇相文的文章

如(rú)何在VB中實現(xiàn)ActiveX控件的IobjectSafety接口

--------------------------------------------------------------------------------

總述
本文叙述了(le)如(rú)何在VB中實現(xiàn)控件的IobjectSafety接口,以标志該控件是腳本安全和初始化(huà)安全的。VB控件默認的處理(lǐ)方式是在注冊表中注冊組件類來(lái)标識其安全性,但(dàn)實現(xiàn)IobjectSafety接口是更好(hǎo)(hǎo)的方法。本言語包括了(le)實現(xiàn)過程中所需的所有代碼。

請注意,控件隻有确确實實是安全的,才能(néng)被标識為(wèi)“安全的”。本文并未論及如(rú)何确保控件的安全性,這(zhè)個(gè)問題請參閱Internet Client Software Development Kit (SDK)中的相關(guān)文檔 "Safe Initialization and Scripting for ActiveX Controls",它在Component Development 欄目中。

相關(guān)信息:
<此處略去了(le)一(yī)段也(yě)許無關(guān)緊要的警告>

現(xiàn)在開始循序漸進地舉例說(shuō)明怎樣創建一(yī)個(gè)簡單的VB控件,以及怎樣将它标識為(wèi)腳本安全和初始化(huà)安全。
首先新(xīn)建一(yī)個(gè)文件夾來(lái)存放(fàng)在本例中所産生(shēng)的文件。

從VB CD-ROM取得OLE 自動化(huà)類庫的制作(zuò)工具。将VB安裝光盤中\Common\Tools\VB\Unsupprt\Typlib\目錄下(xià)所有内容一(yī)并拷貝到前面新(xīn)建的項目文件夾中。


把下(xià)列内容拷貝到“記事(shì)本”中,然後保存到上(shàng)述文件夾,文件名為(wèi)Objsafe.odl:


[
uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
helpstring("VB IObjectSafety Interface"),
version(1.0)
]
library IObjectSafetyTLB
{
importlib("stdole2.tlb");
[
uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
helpstring("IObjectSafety Interface"),
odl
]
interface IObjectSafety:IUnknown {
[helpstring("GetInterfaceSafetyOptions")]
HRESULT GetInterfaceSafetyOptions(
[in] long riid,
[in] long *pdwSupportedOptions,
[in] long *pdwEnabledOptions);

[helpstring("SetInterfaceSafetyOptions")]
HRESULT SetInterfaceSafetyOptions(
[in] long riid,
[in] long dwOptionsSetMask,
[in] long dwEnabledOptions);
}
}
在命令行提示符下(xià)切換到項目文件夾,輸入下(xià)列命令創建一(yī)個(gè).tlb 文件:


MKTYPLIB objsafe.odl /tlb objsafe.tlb
在VB中新(xīn)建一(yī)個(gè)ActiveX Control 項目。修改屬性,把項目命名為(wèi)IobjSafety,控件命名為(wèi)DemoCtl。在控件上(shàng)放(fàng)置一(yī)個(gè)按鈕,命名為(wèi)cmdTest,在它的Click事(shì)件中加入一(yī)句代碼 MsgBox "Test" 。


打開菜單“工程->引用”,點“浏覽”,找到剛剛建立的Objsafe.tlb,把它加入到引用中。


增加一(yī)個(gè)新(xīn)module名為(wèi)basSafeCtl,并在其中加入下(xià)列代碼:


Option Explicit

Public Const IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"
Public Const IID_IPersistStorage = _
"{0000010A-0000-0000-C000-000000000046}"
Public Const IID_IPersistStream = _
"{00000109-0000-0000-C000-000000000046}"
Public Const IID_IPersistPropertyBag = _
"{37D84F60-42CB-11CE-8135-00AA004BB851}"

Public Const INTERFACESAFE_FOR_UNTRUSTED_CALLER = &H1
Public Const INTERFACESAFE_FOR_UNTRUSTED_DATA = &H2
Public Const E_NOINTERFACE = &H80004002
Public Const E_FAIL = &H80004005
Public Const MAX_GUIDLEN = 40

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDest As Any, pSource As Any, ByVal ByteLen As Long)
Public Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As _
Any, ByVal lpstrClsId As Long, ByVal cbMax As Integer) As Long

Public Type udtGUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type

Public m_fSafeForScripting As Boolean
Public m_fSafeForInitializing As Boolean

Sub Main()
m_fSafeForScripting = True
m_fSafeForInitializing = True
End Sub
在工程屬性中把啓動對象改成Sub Main确保上(shàng)述代碼會被執行。m_fSafeForScripting 和m_fSafeForInitializing兩件變量的值分(fēn)别指定了(le)腳本安全和初始化(huà)安全取值。


打開控件代碼窗口,在聲明部分(fēn)加入如(rú)下(xià)代碼(如(rú)果有Option Explicit語句,當然要保證代碼放(fàng)在其後):


Implements IObjectSafety
把下(xià)面兩個(gè)過程代碼拷貝到控件代碼中:


Private Sub IObjectSafety_GetInterfaceSafetyOptions(ByVal riid As _
Long, pdwSupportedOptions As Long, pdwEnabledOptions As Long)

Dim Rc As Long
Dim rClsId As udtGUID
Dim IID As String
Dim bIID() As Byte

pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER Or _
INTERFACESAFE_FOR_UNTRUSTED_DATA

If (riid <> 0) Then
CopyMemory rClsId, ByVal riid, Len(rClsId)

bIID = String$(MAX_GUIDLEN, 0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) - 1
IID = Left$(UCase(bIID), Rc)

Select Case IID
Case IID_IDispatch
pdwEnabledOptions = IIf(m_fSafeForScripting, _
INTERFACESAFE_FOR_UNTRUSTED_CALLER, 0)
Exit Sub
Case IID_IPersistStorage, IID_IPersistStream, _
IID_IPersistPropertyBag
pdwEnabledOptions = IIf(m_fSafeForInitializing, _
INTERFACESAFE_FOR_UNTRUSTED_DATA, 0)
Exit Sub
Case Else
Err.Raise E_NOINTERFACE
Exit Sub
End Select
End If
End Sub

Private Sub IObjectSafety_SetInterfaceSafetyOptions(ByVal riid As _
Long, ByVal dwOptionsSetMask As Long, ByVal dwEnabledOptions As Long)
Dim Rc As Long
Dim rClsId As udtGUID
Dim IID As String
Dim bIID() As Byte

If (riid <> 0) Then
CopyMemory rClsId, ByVal riid, Len(rClsId)

bIID = String$(MAX_GUIDLEN, 0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) - 1
IID = Left$(UCase(bIID), Rc)

Select Case IID
Case IID_IDispatch
If ((dwEnabledOptions And dwOptionsSetMask) <> _
INTERFACESAFE_FOR_UNTRUSTED_CALLER) Then
Err.Raise E_FAIL
Exit Sub
Else
If Not m_fSafeForScripting Then
Err.Raise E_FAIL
End If
Exit Sub
End If

Case IID_IPersistStorage, IID_IPersistStream, _
IID_IPersistPropertyBag
If ((dwEnabledOptions And dwOptionsSetMask) <> _
INTERFACESAFE_FOR_UNTRUSTED_DATA) Then
Err.Raise E_FAIL
Exit Sub
Else
If Not m_fSafeForInitializing Then
Err.Raise E_FAIL
End If
Exit Sub
End If

Case Else
Err.Raise E_NOINTERFACE
Exit Sub
End Select
End If
End Sub
保存後,把工程編譯成OCX文件。現(xiàn)在控件已經實現(xiàn)了(le)IObjectSafety 接口。在.htm中加入這(zhè)件控件試一(yī)試吧(ba)。




在線聯系
點擊這(zhè)裏給我發消息
點擊這(zhè)裏給我發消息
關(guān)注我們