C# Tips
−AxWebBrowserのIInternetSecurityManager−


[トップ] [目次]

WebBrowserコントロールのセキュリティ設定

VisualStudio.NETにあるMicrosoft Web Browserコントロール(AxWebBrowser)のセキュリティ関係を調整する方法です。
ちなみに、Microsoft Web Browserコントロールはshdocvw.dll(ActiveXコントロール)をラップしているだけです。 なので、AxWebBrowserの細かい制御はCOMを使う必要があります。


COM.cs

以下で使うCOMのインターフェースやら#defineやらをC#で使えるようにしたソースです。 長いのでファイルを置いておきます。
COM.cs


Formにインターフェースを実装する

まずは、VisualStudio.NETでFormを作って、そのFormにMicrosoft Web Browserコントロールを貼り付けてください。 あとは、以下のようにインターフェースを継承するようにして、中身を実装してください。


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

namespace ZoneTest
{
    public class Form1 : System.Windows.Forms.Form, COM.IServiceProviderForIInternetSecurityManager, COM.IInternetSecurityManager
    {
           :
         コンストラクタとかもろもろは省略
           :
        
        private void Form1_Load(object sender, System.EventArgs e)
        {
            // ServiceProvider を関連付ける
            object obj = axWebBrowser1.GetOcx();
            COM.IServiceProvider sp = obj as COM.IServiceProvider;
            object ops;
            sp.QueryService(ref COM.SID_SProfferService, ref COM.IID_IProfferService, out ops);
            COM.IProfferService ps = ops as COM.IProfferService;
            int cookie = 0;
            ps.ProfferService(ref COM.IID_IInternetSecurityManager, this, ref cookie);
        }

        #region IServiceProviderForIInternetSecurityManager メンバ
        int COM.IServiceProviderForIInternetSecurityManager.QueryService(ref Guid guidService, ref Guid riid, out COM.IInternetSecurityManager ppvObject)
        {
            ppvObject = null;
            if (guidService == COM.IID_IInternetSecurityManager)
            {
                ppvObject = this as COM.IInternetSecurityManager;
                return COM.S_OK;
            }
            return COM.E_NOINTERFACE;
        }
        #endregion

        #region IInternetSecurityManager メンバ
        int COM.IInternetSecurityManager.SetSecuritySite(COM.IInternetSecurityMgrSite pSite)
        {
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.GetSecuritySite(COM.IInternetSecurityMgrSite pSite)
        {
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.MapUrlToZone(String pwszUrl, out int pdwZone, int dwFlags)
        {
            pdwZone = 0;
            if (pwszUrl == "http://www.yahoo.co.jp/")
            {
                // サンプル:Yahoo! のトップページをローカルマシンゾーンにしてみる
                pdwZone = (int)COM.URLZONE.URLZONE_LOCAL_MACHINE;
                return COM.S_OK;
            }
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
        {
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.ProcessUrlAction(String pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved)
        {
            pPolicy = 0;
            if (dwAction == (int)COM.URLACTION_HTML_SUBMIT_FORMS_TO)
            {
                // サンプル:サブミットを拒否してみる
                pPolicy = (int)COM.URLPOLICY_DISALLOW;
                return COM.S_FALSE;
            }
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.QueryCustomPolicy(String pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved)
        {
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.SetZoneMapping(int dwZone, String lpszPattern, int dwFlags)
        {
            return COM.INET_E_DEFAULT_ACTION;
        }

        int COM.IInternetSecurityManager.GetZoneMappings(int dwZone, out UCOMIEnumString ppenumString, int dwFlags)
        {
            ppenumString = null;
            return COM.INET_E_DEFAULT_ACTION;
        }
        #endregion
    }
}
Form1のコード

ちょっとした解説

まずはFormにIServiceProviderとIInternetSecurityManagerを実装するように、これらを継承元として追加します。 もちろん、Formに実装しなくてはいけないわけではないので別クラスにわけても構いません。
ここでちょっと注意。
IServiceProvider.QueryServiceメソッドは、ほんとうなら


int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);

としたいんです。 けど、3番目の引数がobjectだとどうしてもうまく動きませんでした。 そこで、仕方ないので3番目の引数の型をIInternetSecurityManagerにしたIServiceProviderForIInternetSecurityManagerも定義しています(COM.cs参照)。 そして、FormにはIServiceProviderではなく、IServiceProviderForIInternetSecurityManagerのほうを継承元としています。
(QueryInterfaceしてくれるんならobjectでも良さそうなものだけど、それだとどうしてもIInternetSecurityManagerだと認識してくれなかった)

続いて、Form_LoadイベントでIServiceProviderをFormに問い合わせにくるように登録してやります。

あとは、IServiceProviderForIInternetSecurityManagerとIInternetSecurityManagerを実装するだけです。
IServiceProviderForIInternetSecurityManagerにはQueryServiceメソッドしかありませんし、中身も上記のまんまで十分でしょう。
IInternetSecurityManagerにはいろいろとメソッドがありますが、重要なのはMapUrlToZoneとProcessUrlActionの各メソッドでしょう。
MapUrlToZoneメソッドでは、URLがどのゾーンなのかを返してやります。URLZONE列挙体はCOM.csに入ってます。
ProcessUrlActionメソッドでは、各Actionを許可するか拒否するかを返します。Actionは "URLACTION_" で始まるint値です。これも一通りCOM.csに入ってます。 許可するかどうかはpPolicyにURLPOLICY_ALLOW、URLPOLICY_DISALLOWのいずれかをセットしてやります。 URLPOLICY_QUERYとかもありますが、どういう挙動になるのかは試してません。
ちなみに、これらの値はurlmon.hからコピーしてきてC#の文法にあわせただけです(コメントとかもそのまんま)。


[トップ] [目次]

株式会社ディーバ 青柳 臣一
2003/09/17