.NET 控件的許可驗證方案


 伴隨着.net開發技術的成熟,軟件開發進入控件化時代。越來越多的公司投入軟件開發領域,企圖控制軟件產業鏈的上游:提供解決方案。其中一部分公司就是提供控件。控件對外就象是一個黑盒子,藉助於方法,屬性和事件,開發人員即可輕易的開發出專業的應用程序,與此同時,軟件的保護方法也不斷出現。在共享軟件時代,軟件開發人員開發好程序,然後設計一個序列號生成算法,對正式許可的用戶發佈序列號,生成註冊文件。在應用程序啓動時檢查註冊文件,如果有則繼續運行,否則中止運行或是提供部分功能。
.net 技術的出現,也提供了相應的軟件保護解決方案。本文詳細討論.net 技術的軟件保護方案與實現。我們可以採用各種方式來生產許可,授權用戶使用我們開發的控件。常見的方式如下:
  1. 註冊表。在控件安裝時,在註冊表中寫入相應的鍵值,在控件運行時,查找該鍵,如找不到則拋出異常;
  2. 許可文件。在控件運行時,查找許可文件,如找不到,則拋出異常;
  3. 遠程Web服務驗證。在控件運行時,連接到遠程的許可驗證服務器,如能找到值,則表示已經授權;

  註冊表的驗證方式實現起來容易,但是也很容易發生驗證異常。如果用戶裝有註冊表監控程序,跟蹤對註冊表的每一項改動,則會很容易定位到鍵值,進而分析和利用,此外,這種方式對XCOPY也有影響,不方便部署應用程序;許可文件根據用戶的硬件信息,比如硬盤序列號,或是MAC地址,郵件,生成一個許可文件,放在控件可以找到的地方,在運行時找到該許可文件,如果找不到,則阻止控件的運行;遠程Web服務需用客戶端能聯網,在控件運行時向服務器發出查詢許可的命令,如果找不到,則停止運行;如果用戶不聯網,這種方式有侷限性,用戶根本不能在脫機的情況下嘗試運行該控件。

需要理解的對象:LicenseProvider

  MSDN中的解釋是:提供 abstract 基類以便實現許可證提供程序。從 LicenseProvider 繼承時,必須重寫 GetLicense 方法。我們可以理解爲一個許可證的提供程序,在控件需要驗證時,提供許可授權,如果不提供許可,則不能使用該控件,拋出異常。這是個抽象類,不允許實例化,我們從該類派生,並且重寫GetLicense方法。

public class  FileLicenseProvider : System.ComponentModel.LicenseProvider
      {
          public override License  GetLicense(LicenseContext context, Type type, object instance, bool  allowExceptions)
          {
              if (context.UsageMode ==  LicenseUsageMode.Designtime)
              {
                  // 開發人員設計時不需要許可,直接頒發許可證
                  return new FileLicense(this,  "The App");
              }
              else
              {      
                  string licenseFile =  Path.Combine(AppDomain.CurrentDomain.BaseDirectory,  type.FullName+".lic");
                  if (File.Exists(licenseFile))
                      return new FileLicense(this,  "The App");
                  else
                      return null;
              }
          }
      }

  通過覆蓋GetLicense方法,我們獲取需要驗證的控件的類型信息,然後在當前應用程序目錄下查找以控件的lic文件,如找到,頒發許可,否則返回null值。

License

  MSDN中的解釋爲:爲所有許可證提供 abstract 基類。向控件的特定實例授予許可證。通俗的理解就是許可,給控件頒發的許可,表示控件已經授權過了,可以被使用。下面的代碼可以幫助您理解許可的含義。

public class  FileLicense : System.ComponentModel.License
      {
          //許可驗證提供程序
          private FileLicenseProvider owner;
          private string key;
          public FileLicense(FileLicenseProvider  owner, string key)
          {
            this.owner = owner;
            this.key = key;
      }

    //許可Key,通俗的理解是序列號。
          public override string LicenseKey
          {
            get
            {
              return key;
            }
          }

          public override void Dispose()
          {

          }
      }

FileLicense會應用到控件上,如果返回給控件的FileLicense爲空,則控件會拋出異常。

應用許可提供程序

開發一個控件,如何應用許可驗證呢?

如下代碼所示,我們開發一個MyControl的控件,同時給它加上LicenseProvider特性(attribute),這樣在該控件運行時,會用FileLicenseProvider來實行許可驗證。

[LicenseProvider(typeof(FileLicenseProvider))]
public class MyControl : WebControl

此外,我們還需要在控件的構造方法中進一步調用驗證方式:

public MyControl()
      {
          try
          {
              license =  LicenseManager.Validate(typeof(MyControl), this);
          }
          catch
   {
               HttpContext.Current.Response.Write("MyControl控件未授權,請聯繫程序開發商");
          }
      }

  如果該控件獲取正確的授權,則會繼續運行,否則因得不到許可而不能繼續生成。 LicenseManager類會找到FileLicenseProvider類的GetLicense方法,來獲取許可,經過各種驗證方式(註冊表,許可文件)來提供許可實例,如果驗證失敗,則會拋出LicenseException,表示無法找到許可。

許可驗證服務器

  在註冊表驗證方式中,我們需要在控件的安裝程序中嵌入腳本,在註冊表中寫入相應的鍵值;在本地許可文件驗證方式下,我們需要根據序列號生產相應的許可文件;在遠程Web服務的驗證方式下,我們還需要設計一個遠程的驗證服務器,接受客戶端的驗證請求。 下面我們來討論一下如何設計這個服務器應用程序。
  Web服務是跨平臺的通用協議,藉助於SOAP(簡單對象訪問協議),我們能接受各種平臺的驗證請求。
藉助於ASP.NET Web服務,我們可以輕易的實現這個服務器端應用。 打開Visual Studio 2008,新建ASP.NET Web Service Application


圖一 新建Web Service

把新建的服務名稱改LicenseService.asmx,然後在該服務中提供驗證方法

[WebMethod]
      public bool  ValidateLicense(string mac)
      {
  bool  ret = Validate(mac);
  return  ret;
      }

Validate方法會去查找數據庫記錄,返回結果,提供給客戶端。 爲此,我們還需要設計數據庫。


圖二 SQL設計視圖

  這裏,我們採用驗證客戶端MAC地址的方式,如果能找到該地址,則把Enabled設爲1,否則找不到,表示該MAC地址未授權,返回false給許可驗證提供程序。SQL 腳本如下:

CREATE TABLE [dbo].[LicenseUser](
      [MAC] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
      [Enabled] [smallint] NULL,
CONSTRAINT [PK_LicenseUser] PRIMARY KEY CLUSTERED
(
      [MAC] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

應用程序

由於開發的是Web控件,我們設計一個Web站點,來測試我們的控件保護方案。右擊解決方案,添加現有站點(Web site)


圖三 添加現有站點

把我們的控件從工具欄中拖動到一個Web頁面中,生成應用程序,然後F5,調試運行。頁面的源代碼如下:

 <uc:MyControl ID="MyControl1" runat="server" />

另外,在Web.config中添加如下代碼,您可以不必在每一個頁面中都加入控件引用。

<pages>
  <controls>                 
        <add tagPrefix="uc" namespace="HTSystem"  assembly="HTSystem.Component,
        Version=1.1.0.0, Culture=neutral,  PublicKeyToken=c2c8c99b69b1086e"/>
        </controls>
  </pages> 

您可能也注意到了,我們給自己寫的組件MyControl添加了版本和強命名元數據,這樣可以保護我們的組件。

總結

  本文試圖給您提供幾種常用的許可驗證的方式。文中詳細討論了許可文件的驗證方案,分析瞭如何藉助Web服務技術,設計遠程驗證服務器,另外,您還應該瞭解註冊表的方式的驗證方式。 您可以通過閱讀源代碼,詳細瞭解這三種方式的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章