星期二, 12月 24, 2013

CAS Client for .NET renew="true"

過去不算短的一段時間,一直都是在本機 IIS Express 開兩個埠模擬兩個不同的網站,它們都裝上 CAS Client for .NET 來測試單一簽入,好像沒問題?今天深究為何 renew 的值不論怎麼設的效果都一樣之下,才大吃一驚:由於兩個網站都在 localhost,所以根本就共享 Cookie!

為了要確認此參數有效,整個測試環境大修:
  1. CAS Server 必須安裝憑證。
  2. 瀏覽器所在電腦必須信任該憑證,各網站以 https 連入 CAS Server。
  3. 即使兩個網站都在本機,也要設 C:\Windows\system32\drivers\etc\hosts 給它們不同的主機名稱,例如 www.ap1.com 與 www.ap2.com。
  4. 登入後,利用瀏覽器不同的頁籤訪問 renew="false" 的網站,可正常使用;但若設定 renew="true" 的網站,則必須重新登入。

星期一, 12月 09, 2013

如何確認 PreparedStatement 有在 Oracle 被執行到?

假設程式如下:

String s = "Select COUNT(*) From TABLE1 Where ID = ?";
PreparedStatement p = connection.prepareStatement(s);
Object o = (Object)"id";
p.setObject(1, o);
ResultSet r = p.executeQuery();

可以藉由 Oracle SQL Developer 執行以下的查詢(在程式執行前後各一次):

Select FETCHES From V$SQL Where SQL_TEXT = 'Select COUNT(*) From TABLE1 Where ID = :1';

如果控制在很短的時間內,第二次的結果比前次多一,則幾乎可以確定這個敘述有被執行到。其中 V$SQL 或是 V$SQLAREA 是一個內建的統計用 View,FETCHES 是這個 View 的一個欄位,SQL_TEXT 是 SQL Statement,「:1」表示查詢語句的第一個變數。

星期一, 11月 18, 2013

Virtual Box Shared Folder for Ubuntu as Guest

當 Windows 作為 VirtualBox Guest 時,要設定 Host 上的一個目錄可在 Guest 共享是很容易的,但到 Linux 做為 Guest 時則有點麻煩,原因是多了一個「掛載」的觀念,而且權限也要注意,在此稍微摘要一下(以 VirtualBox 4.2.18 + Ubuntu 12.04 為例):
  • Guest 當然還是要 Install Guest Additions
  • Shared Folder 當然還是要設,下例是命名為 shared
  • 建立一個目錄準備用來對應 Host 分享出來的目錄,下例是在一位普通使用者 user1 桌面上的 SharedByHost 目錄
  • 掛載共享目錄:sudo -t vboxsf shared /home/user1/Desktop/SharedByHost
如此一來還只做了一半,因為 SharedByHost 只能由 root 存取,若想讓 user1 共享就還要:
  • id user1 -> 取得 user1 的 uid,下例是 1000
  • sudo -t vboxsf -o uid=1000 shared /home/user1/Desktop/SharedByHost
以上即可讓 user1 存取到 Host 分享出來的目錄,不過 Guest 重啟之後還是要再掛載才有效,否則 SharedByHost 會是個空目錄。

後記:VirtualBox 4.3.2 + Ubuntu 13.10 略有改善,共享目錄會自動掛載於 /media,並加 sf_ 前綴,而在權限方面是賦予 root 使用者與 vboxsf 群組,所以更簡單的方法是將 user1 加入 vboxsf:
  • usermod -a -G vboxsf user1

星期五, 11月 15, 2013

首度測通非 Windows 平台經瀏覽器存取 SmartCard 憑證卡

以下的順序非常重要,顛倒了就會困難重重:
  • Ubuntu 12.04 (32bit)
  • PC/SC
  • EZ100PU driver
  • /etc/rc.local: /usr/sbin/pcscd&
  • reboot
  • card reader (with any? smart card) testing ok
  • JRE
  • libHicos_p11v1.so: [JRE_HOME]/lib/i386
  • view html with signed java applet
[2014/02/06 補充]
由於上個月 Java 7u51 推出,不得不更新,否則瀏覽器(還是 Java 本身?)會抱怨版本太舊。而更新會有一些連帶要求:
  • 標示所需的 Permissions 與 Codebase,可參考這個連結
  • 若是自簽憑證,請在 Java 的控制面板「安全」頁籤,管理憑證、匯入簽署用的憑證到「Signer CA」。千萬注意,不是「Trusted Certificates」!

星期四, 10月 17, 2013

自修手錶

手錶快沒電了,一次走兩秒。昨天換了電池與防水墊圈之後,碼錶歸零歪得更嚴重,修錶的老闆說沒辦法,心裏很鬱悶。本想送原廠修的,所以上官網,無意中發現說明書上就有教怎麼調回來,感覺撿回一隻新錶的高興。

星期五, 10月 04, 2013

星期一, 9月 30, 2013

Mac Contacts 匯入中文亂碼

由於姓名地址都是中文的關係,過去一直無法將其他軟體的通訊錄匯入到 Mac Contacts(中文變亂碼),今天終於找到解法:要事先將準備匯入的文字檔轉碼為 UTF-16。

星期五, 9月 27, 2013

What's SOAP?

在今年台灣微軟大拜拜的某一場中,講者指著一張肥皂的圖問台下「這是什麼技術?」,有人回答 WebServices,竟然被打槍?我正猜著他有什麼更高明的答案,果然台下再也沒人答對,講者最後公佈了是「WCF」,差點當場吐血。這是 MVP 的水準嗎?

Spring.NET Extensible XML authoring

基本上照著官方文件附錄 C 做,沒什麼太大問題,看人家的文件多好!有些地方我想補充一下:
  1. XSD 很希望只有一份,但目前要有兩份一模一樣的,這個比較遺憾。一份放在組件內且必須設為「Embedded Resource」,另一份放在網站上公佈。
  2. 依據 XSD 在組件專案的位置決定 MyNamespaceParser 的 SchemaLocation 值,以我的例子,專案預設命名空間是 com.abc,目錄為 spring/webflow/config,檔名為 spring-webflow-config-1.0.xsd,所以我的 SchemaLocation = "/com.abc.spring.webflow.config/spring-webflow-config-1.0.xsd"。
  3. 我自訂的 xml namespace 叫 webflow,所以在 Spring 的設定像是
    • <objects xmlns="http://www.springframework.net"
    •          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    •          xmlns:webflow="http://www.springframework.net/schema/webflow-config"
    •          xsi:schemaLocation="
    •          http://www.springframework.net
    •          http://www.springframework.net/schema/objects/spring-objects-1.1.xsd
    •          http://www.springframework.net/schema/webflow-config
    •          http://10.0.2.2/spring-webflow-config-1.0.xsd
    •          ">
  4. 前述設定倒數第二行就是所謂「放在網站上公佈」的複本位置,如果不放,在 Visual Studio 開發環境看來會有些不足,但不至於影響正常執行。另外,由於實際上發現在 IIS 的網站上可能會有 Mime-type 設定等等問題,最後我用的是 Apache httpd。
  5. 前述設定第三行要與 MyNamespaceParser 的 Namespace 值匹配。

星期五, 9月 13, 2013

Migrate Spring *.properties to Spring.NET (version 2.0.0-M2)

假設原來的 *.properties 內容這麼簡單:
  • key1=value1
  • key2=${key1}value2
要搬到 Spring.NET,除了不認 java.util.Properties 這個因素,必須改成 xml 之外,還有很多文件上都找不到的怪招。總之先看答案(propertiesHolder.xml):
  • <?xml version="1.0" encoding="utf-8"?>
  • <configuration>
  • <spring-config>
  • <add key="key1" value="value1" />
  • <add key="key2" value="${key1}value2" />
  • </spring-config>
  • </configuration>
另外,要指到這個檔案必須藉由以下組態設定:
  • <object type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer">
  • <property name="location" value="file://~/propertiesHolder.xml" />
  • </object>
至於節點為什麼一定要叫 spring-config?為什麼結構一定要這麼大?暫時保留,湊出這個答案已經浪費太多時間,無力再找原因了。

星期二, 9月 10, 2013

signtool.exe error: 0x800703f0

在使用憑證卡簽署元件時,我曾多次遇到這個問題,看來是隨機且無奈的,不過最近總算比較清楚。由於微軟有個「Windows Root Certificate Program」,在計畫名單上的根憑證都是 On-Demand 自動安裝,但安裝的速度我們無法控制,因此很有可能在首次使用某種憑證時一直簽不過,但下次莫名其妙地又好了。如果要完全避免這個問題,可以事先手動安裝
  • 信任根憑證
  • 中繼憑證
  • 個人憑證(簽署用憑證裝在此)

星期二, 9月 03, 2013

Common Logging for .NET @ Visual Studio

首先要更正我在前一篇文章的錯誤:Spring.NET 只需要 Common Logging for .NET(而且是較舊的版本),並沒有相依於 log4net,所以在使用 Spring.NET Framework 的開發中,如果不希望額外增加參考,可以藉由以下幾項達成:
  • <configuration>
      <configSections>
        <sectionGroup name="common">
          <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
        </sectionGroup>
      </configSections>
      <common>
        <logging>
          <factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
            <arg key="level" value="INFO" />
          </factoryAdapter>
        </logging>
      </common>
  • private static Common.Logging.ILog log = Common.Logging.LogManager.GetLogger(typeof(MyClass));
  • log.Info("myInfo");
如此一來,記錄會出現在 Visual Studio 的 Output 視窗。

星期二, 8月 20, 2013

Windows 8.1 + IE 11 can't visit localhost?

部署在本機 IIS 8 的純網頁,原本在 Windows 8 + IE 10 都好好的,換到 Windows 8.1 + IE 11 竟然都看不到了?請出 Fiddler 也一樣徒勞?Google 一下,網路上還真的有幾篇文章在談這件事,說是防火牆要如何如何,有什麼辦法改等等,其實都太麻煩了。關鍵只在於:
  • 網際網路選項=>進階=>Enhanced Protected Mode 優先於某區域(網際網路/近端內部網路)的 Protected Mode,若前者未勾選,後者勾選是無效的;但兩者皆勾選,將阻止該區域來自於本機的 Routing。
  • Windows 8 + IE 10 預設 Enhanced Protected Mode Off,但 Windows 8.1 + IE 11 預設 Enhanced Protected Mode On。

星期三, 8月 14, 2013

OpenOffice Impress on Mac 字體問題

在 Mac 安裝 OpenOffice 之後,使用 Impress 簡報會有中文字大小不一的問題,需要從安裝微軟作業系統的電腦上「借」新細明體來解決。

星期二, 7月 23, 2013

政府測試憑證的問題

從今年三月起,由於保證等級的問題,測試憑證管理中心必須獨立出來。但直到最近,發出來的測試憑證關於「發行單位」的憑證連結,仍然是指向舊的。寫信去反映,倒是很快(半天)得到答案:請自行下載。意思是不理我就對了。
錯的事情不改正,這就是我們的政府,或懷有國營事業心態的承商。也對啦,這又不是什麼大事,軍中都能整死人了,沒有體制只靠人治豈不多見?

Mac 常失眠

自從改用 Mail 收信,我的 MacBook 就常失眠,每次蓋上螢幕拔電拔網路下班,到家就一付熱到快爆炸的樣子。原來是因為電源管理預設插座供電時,即使休眠也要繼續收信,難道蘋果認為大家都已經有吃到飽的網路了?找解法的過程並不順利,一度曾以為可以了,過幾天又出狀況。經過約一個月的驗證,最後的做法是增加一個「沒有網路」的網路組態,每次下班前都是調到這再蓋螢幕拔電拔網路,應該是確定可以了。

星期四, 7月 18, 2013

Visual Studio 2013 Preview Bug?

有兩個都是 .NET 2.0 的專案,專案一依賴專案二,專案二建置沒問題,但專案一在 Visual Studio 2013 Preview 始終無法建置,非得升到 .NET 4.0 不可,而這情形在以前的 Visual Studio 2012 並不存在。
比較值得懷疑的,是專案二有參考到 COM 元件,不知道那個 Interop 介面(也重新產生過)是不是綁到 .NET 4.0 去了?用 ildasm.exe 一看,果然沒錯。歸根究底,與開發工具自動產生的 Interop 介面有關,VS2012 用 .NET 2.0 的 Tlbimp.exe,而 VS2013 用 .NET 4.0 的 Tlbimp.exe。知道原因後,想解決這個問題就簡單了,自已在命令列用適當的工具產生即可,例如:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\Tlbimp xxx.dll -> 2.0
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\Tlbimp xxx.dll -> 4.0

星期三, 7月 17, 2013

cabarc.exe 藏身之地

原本有一個專屬的 Cabinet SDK,但很久以前就找不到微軟官網下載點了,所以一直用別家網站留的,不是很放心。如果是比較單純的狀況,MakeCab.exe 也許勉強能用,在系統目錄就已內建。今天發現在 IEAK 10 竟然有含,相信 IEAK 9、IEAK 8 也是吧?下次有空再驗證。

安裝玉山銀行 WebATM 之後的 Mac 無法在 VM Guest 用讀卡機

玉山銀行的 WebATM 首先能在 Mac 使用晶片讀卡機,做得漂亮!可惜一但安裝,虛擬機器的讀卡機就會因「忙碌」而連不上,即便是關閉瀏覽器甚至重開機都無效。
究其原因,有一個「pcscd」持續地佔住讀卡機,即使原先不在,只要一插上就歸它管,而且這個程序殺了一秒鐘又會再起來,所以想「暫停」得費點工夫:
  • ps -ef | grep pcscd | grep -v grep | awk '{print $8 "\t" $2}' -> 取得 path 與 processId
  • sudo chmod -x path
  • sudo kill processId
當虛擬機器不再使用,想要恢復 WebATM 時:
  • sudo chmod +x path
[2013/08/13 補充]
後來發現兩個缺點:一是因為找不到原來的 path 而無法恢復,二是在 Consloe 會有很多錯誤訊息,所以那只是個治標不治本的爛方法呀!依據錯誤訊息為線索,在我的機器上可以找到 /Library/LaunchDaemons/org.opensc.pcscd.plist 以及 /Library/LaunchDaemons/org.opensc.pcscd.autostart 兩個內容一模一樣的檔案,而且那個找不回來的 path 都出現了。所以想「暫停」的步驟可改成:
  • sudo launchctl unload /Library/LaunchDaemons/org.opensc.pcscd.plist
  • (可省略)sudo rm /Library/LaunchDaemons/org.opensc.pcscd.plist
恢復:
  • (可省略)sudo cp /Library/LaunchDaemons/org.opensc.pcscd.autostart /Library/LaunchDaemons/org.opensc.pcscd.plist
  • sudo launchctl load /Library/LaunchDaemons/org.opensc.pcscd.plist
  • (如果前一次用的是舊方法暫停,再加上)sudo chmod +x path
[2015/08/24 補充]
Yosemite 已不再使用 pcscd,所以招術失靈,請參考這篇

星期一, 7月 15, 2013

信任一個懶惰又小氣的安全網站

要從標題這句話倒過來解釋:
  • 安全網站:傳輸過程經 SSL 安全通道加密。
  • 小氣:或者可以說「節儉」,不願交保護費給 Verisign 這類大公司。自簽根憑證,再據以發行網站憑證。
  • 懶惰:不積極宣導如何信任我的網站,也沒有提供散佈憑證的安全管道。
  • 信任:安裝對方的自簽根憑證。
首先要取得對方的自簽根憑證:在 Windows 作業系統,最簡單的方式是用 Firefox,到了這種網站之後選「我了解此安全風險」、「新增例外網站」、「取得憑證」、「檢視」、「詳細資訊」、「(最上一個)憑證層級」、「匯出」、「儲存」到一個臨時檔案。
接下來是安裝:此時可以關閉 Firefox,然後在該檔點兩下,「安裝憑證」到「使用者」或「電腦」的「受信任」,或「電腦」的「第三方」根憑證存放區,如此一來不論是透過 IE 或 Chrome 都已信任這個安全網站。至於 Firefox 請到「選項」、「進階」、「檢視憑證清單」、「憑證機構」、「匯入」上述的臨時檔案。

[2014/06/05]

到了最近比較新的作業系統,例如 Windows 8.1,可能要改放到「受信任的人」憑證存放區。

星期四, 7月 11, 2013

不是 Cross-origin resource sharing 難,而是⋯⋯

整理幾個最近遭遇的問題:
  1. Microsoft IE 11.0.9431.0 在 localhost 但 port 不同的情況下,認為這不算跨域,沒作預檢(preflight),直接發送真正需要的 Request。
  2. Google Chrome 28.0.1500.71 即使預檢失敗,仍會發送真正需要的 Request。
  3. Microsoft IIS 8 即使未設 Access-Control-Allow-Methods,仍接受 GET、OPTIONS。
  4. System.Web.Http.ApiController 的子類別最好多寫一個空的方法「public void Options() { }」,否則 Firefox 預檢失敗,就不發送真正需要的 Request 了,雖然這是最標準的,但讓我誤會了好幾個小時,以為怎麼 IE 10、Chrome 都正常,唯獨 Firefox 不行?

星期三, 7月 10, 2013

從瀏覽器呼叫 Restful Web API 的要訣

前文所提,瀏覽器要支援 Cross-origin resource sharing,Firefox 或 Chrome 都沒問題,IE 只有 10 或更新的版本才有機會,而且要看文件模式(Document Mode)是不是「標準」或「相容」(Quirks),若其他像是 Internet Explorer 9 standards、Internet Explorer 8 standards 等都不行。
問題來了,若使用者雖然是 IE 10,但他調成不支援的文件模式,要如何交待?這時必須先用 JavaScript 偵測,並在不符條件的情況下提示。但用 navigator.userAgent 是無效的,因為它只對瀏覽模式(Browser Mode)有反應,對文件模式一無所知。幸好 IE 還有個特別的屬性叫 document.documentMode,如果小於 10 再提示就對了。
網路上也有人提到,即使是 IE 8 或 IE 9,還是有機會支援,只是限制一大堆。但連 jQuery 都明確表態不會採納了,我這種小角色又何必為難自己?

星期二, 7月 09, 2013

英國鍵盤不等於英文鍵盤

我的 Windows 8 是「英國英文版」,不知是否當初買錯了?相對於熟悉的「美式國際鍵盤」排列,「@」和「"」的位置是對調的,更糟的是「#」變成英鎊符號。

星期五, 7月 05, 2013

JSONP 的真相

現在很流行用 Ajax 到伺服端要物件回瀏覽器呈現,物件怎麼從 HTTP 上走下來?靠的就是 JSON。那 JSONP 呢?原本僅以 JSON 回傳物件,多加的 P 是指 Padding,填補成「對回呼函式的呼叫」,而 JSON 改用來封裝呼叫函式時的引數。

Restful Web API 服務與測試分離

過去我的 Restful Web API 在跨域限制下為了方便,都把服務本身與測試服務的網頁放在同一個網站,但這讓人蠻不舒服的。想要把它們分開,網路上大致流傳著兩種解法:JSONP 與 Cross-origin resource sharing,研究之後發現,前者其實改變了服務的介面,不敢領教,所以決定用後者。有幾個要點(假設服務在 http://localhost/myService,測試首頁在 http://localhost:12345/test.html):
  • 服務端要設定對測試來源開放,以 IIS 7 為例,在 Web.config configuration -> system.webServer -> httpProtocol -> customHeaders 需要以下的節點:<add name="Access-Control-Allow-Origin" value="http://localhost:12345" />
  • 測試端我用的是 jQuery 發送 Ajax,它當然也要知道服務在哪提供,像這樣:$.ajax({url: "http://localhost/myService", success: ..., error: ...});
  • 測試端使用的瀏覽器會挑,像 IE 10 以前都不行,但 Firefox、Chrome 就沒這問題,可能要注意一下。
  • 若在 Visual Studio 同一 Solution,StartUp Project 設在測試專案,Start Page 設在測試首頁,服務專案的 Properties -> Web -> Start Actions 設在「Don't open a page. Wait for a request from an external application.」,這樣才會同時載入兩個網站。

星期四, 7月 04, 2013

在 ASP.NET 做簡單的 Ajax + JSON 測試

  1. Visual Studio 新建方案,範本挑 ASP.NET Empty Web Application 就可以了,其他較複雜的應該更沒問題。
  2. .NET Framework 版本沒特別要求,現在的 2.0 到 4.5 都可以。
  3. Web.config 沒什麼要加要改的。
  4. 這次實驗用的是 jquery-1.8.2.min.js,但版本應該沒什麼限制。
  5. 新建測試首頁,名為 Test.html
    • <script type="text/javascript" src="jquery-1.8.2.min.js"></script>
    • function query() {
          $.ajax({
              url: "/Test.ashx",
              success: function (time) {
                  $("#timeCell").text(time.now);
              }
          });
      }
    • <input type="button" onclick="query()" value="query" />
    • <td id="timeCell"></td>
  6. 新建 Generic Handler,名為 Test.ashx
    • using System;
    • using System.Web;
    • public void ProcessRequest(HttpContext context)
      {
          context.Response.ContentType = "text/json";
          context.Response.Write("{\"now\": \"" + DateTime.Now + "\"}");
      }

簡易 Workflow

在 Java 的世界有 Activiti,微軟的 Workflow Fundation 硬是輸人一大截,連拉個流程都要先寫一個 WPF 程式,還好照 MSDN 抄來再改就可以了。剛開始一時看不懂,怎麼範例文件上人家有的我都沒有?原來是要裝 Visual Studio Express for Desktop 才行,for Web 幫不上忙的。

IIS Express 開放非本機電腦連入

IIS Express 預設是只讓本機的瀏覽器連入,但有時這不夠,例如要從虛擬機器進來,或是代理伺服器的限制等。其實很容易改,只要找 IISExpress\config\applicationhost.config 檔案中相關的站台設定,類似以下片段(假設是 http://localhost:54321):
<configuration>
    <system.applicationHost>
        <sites>
            <site>
                <application>...</application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:54321:localhost" />
                </bindings>
            </site>
        </sites>
    </system.applicationHost>
</configuration>
只要將 localhost 刪除就好了,該行變成像這樣:
...
<binding protocol="http" bindingInformation="*:54321:" />
...
記得存檔後重啟 IIS Express,而且因為開放的對象變大,權限也要隨之提高。像我都是利用 Visual Studio Express 啟動,要記得開發工具本身也必須「以系統管理員身分執行」。
有時也會遇到所謂「非本機」其實還是本機,但就是不能從 http://localhosthttp://127.0.0.1 來,非要走 http://computername 這條路,但本機的網路怎知 computername 就是我?這種情況下就去編輯 C:\Windows\System32\drivers\etc\hosts 吧。

星期一, 6月 03, 2013

Visual Studio Express: Build Events

  • C#: Support.
  • VB.NET: Visual Basic Express does not support entry of build events. This is supported only in the full Visual Studio product.

星期一, 5月 27, 2013

查詢 .Net 組件的 Public Key Token

sn.exe -T assembly
至於 sn 這個強式名稱工具的所在位置,請參考我另一篇所提到的 SDK 路徑。

星期四, 5月 23, 2013

Visual Studio 2012 MVC4 Web API 錯誤處理

  1. 由繼承 ApiController 的子類別拋出 System.Web.Http.HttpResponseException。
  2. 假設用戶端由 jQuery 處理 ajax,像以下的程式片段:
  3. statusCode: {
    400: function() {
    // do something
    },
    401: function() {
    // do something
    }
    }
    或這樣處理也可以
    error: function (jqXHR, textStatus, errorThrown) {
    // jqXHR.status, errorThrown
    }

星期四, 5月 16, 2013

用 Visual Studio 開發 Web 之前就要準備的 log 機制

  1. 先由套件管理抓 Common.Logging 2.1.2 並設為專案參考。
  2. Web.config 新增如下的部份,注意:TraceAppender 會讓記錄往開發工具的 Output 送。
  3. 要記 log 的各類別必須有 private Common.Logging.ILog log = Common.Logging.LogManager.GetCurrentClassLogger();
  4. 真的要記 log 的程式是 log.Info("xxx");
<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
  </configSections>
  <common>
    <logging>
      <factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
        <arg key="level" value="INFO"/>
      </factoryAdapter>
    </logging>
  </common>
  ...
</configuration>

星期三, 5月 15, 2013

在 Visual Studio 2012 MVC 4 專案,以最小修改納入 Spring.NET

  1. 新建專案,範本選「ASP.NET MVC 4 Web Application」,專案名稱與方案名稱都一樣是 SpringMvc4,如此一來,專案預設的命名空間與組件名稱也會一樣。較細的範本種類,選預設「Internet Application」即可。
  2. 在 HomeController.cs 增加 protected string Message { get; set; },修改 Index() 方法中 ViewBag.Message = Message;
  3. TOOLS -> Library Package Manager -> Manage NuGet Packages for Solution... 下載 Spring.Web.Mvc4(如果搜尋不到,可能是範圍的關係,要從 Stable Only 改成 Include Prerelease)。
  4. 修改 Global.asax.cs,繼承 Spring.Web.Mvc.SpringMvcApplication。
  5. 在 Web.config 調整 Common.Logging 的 bindingRedirect: 0.0.0.0-2.1.1.0 -> 1.2.0.0,同時也要增加:

完成!請看首頁是否有來自於設定檔注入的字串呢?

[2015/11/29 補充]
Visual Studio 2015 + Spring.Web.Mvc5 大致上依然適用,而且在第 3, 5 點都有改進了。

星期二, 5月 14, 2013

組件版本重導(Redirecting Assembly Versions)

當被參考的組件發佈新版,上層的組件或應用程式重新編譯再測試是比較正確的做法。但實務上有時會遭遇困難,應變的方法有二:
  • 由組件發行者發佈 Publisher Policy 部署在呼叫端
  • 由組件呼叫端編寫 Configuration
其實這兩者都採用一致的 XML 語法,官網相關說明在,幸好微軟沒有在這個問題上進一步折磨我們開發者。

附帶一提:這裏談的是強式名稱簽署的組件,未簽署的組件版本不重要。

在 Visual Studio 2012 Express 曾有一個 Bug:若在測試專案放 app.config 是沒用的,在 Update 1 以後悄悄地解決了,所以「要跟就得跟緊」。

.NET Framework 4.0 的一些改變

  • GAC
    • 3.5 %WinDir%\assembly
    • 4.0 %WinDir%\Microsoft.NET\assembly
  • SDK
    • 3.5 %ProgramFiles(X86)%\Microsoft SDKs\Windows\v7.0A\bin
    • 4.0 %ProgramFiles(X86)%\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools

星期二, 4月 23, 2013

在 BootCamp 安裝的 Windows 8 無法使用觸控板 click?

  1. 首先應確認驅動程式已安裝,在裝置管理員沒有黄色驚歎號。
  2. 搜尋「設定」而非「應用程式」,找到 BootCamp,進入後有個觸控板專屬頁籤可設。

星期五, 4月 19, 2013

牛頭不對馬嘴

80040154 是微軟給「找不到元件」的錯誤代碼,比較豐富的除錯訊息還會包含 CLSID、目錄位置,但要如何解決,可能有很多方法吧?搬檔案、調權限、改機碼、註冊等等。這次遇到一個最離譜的:在 32 位元開發環境下建置的網站,移到 64 位元的伺服器,要針對應用程式集區 Enable 32 bits Application,至於元件本身是完全沒問題的。

星期三, 4月 03, 2013

Java keytool / jarsigner 藉由 PKCS#11 標準存取智慧卡上的憑證

首先需要智慧卡憑證本身的驅動程式(例如 C:\Windows\HiCOSPKCS11.dll),再來準備一個組態檔,姑且命名為 HiCOS.cfg,內容如下:

name = HiCOS
library = C:\Windows\HiCOSPKCS11.dll

執行 keytool 時帶這些參數:

keytool -providerClass sun.security.pkcs11.SunPKCS11 -providerArg HiCOS.cfg -keystore NONE -storetype PKCS11 -list

執行 jarsigner 也類似:

jarsigner -providerClass sun.security.pkcs11.SunPKCS11 -providerArg HiCOS.cfg -keystore NONE -storetype PKCS11 my.jar cert1

星期三, 3月 20, 2013

如何用自簽憑證測試 Tomcat / IIS SSL

首先是製作自簽憑證,最大眾化的工具是 Java keytool,指令如下(所有字的部份都可以依個別情況修改):

keytool -genkeypair -alias a -keystore store.pfx -storetype pkcs12 -keyalg RSA -dname "CN=www.xyz.com,OU=Unit,O=Organization,L=City,S=State,C=US" -keypass password -storepass password

接著暫時先看 Tomcat 6.x,假設上述產出的 store.pfx 放在 conf 目錄下,再來是在 server.xml 設定以下段落:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           keystoreFile="conf/store.pfx"
           keystoreType="pkcs12" keystorePass="password"
           truststoreFile="conf/store.pfx"
           truststoreType="pkcs12" truststorePass="password"
           clientAuth="false" sslProtocol="TLS" />

在用 IE 測試前,網際網路選項->內容->憑證->受信任的根憑證授權單位->匯入 store.pfx,接著開 Tomcat https 的網頁即可。

至於 IIS 7.5 則比較簡單,先在 IIS 管理員匯入伺服器憑證,當然還是 store.pfx,「允許匯出此憑證」需保持勾選;然後是 SSL 設定->繫結即可。

[2013/08/15 補充]
  1. 在 store 只有一個 key 的情況下,也就是上例,別名(alias)可有可無。
  2. CN= 的內容必須與提供外界訪問的網域名稱完全相符,在本機測試時,當然也可以是電腦名稱或是 localhost。
  3. -storetype pkcs12 如果省略的話,會是另一種 keytool 預設的格式,IIS 可能不支援,Tomcat 應該會支援,Jetty 只支援這種,不接受 pkcs12。
  4. keytool 預設格式的 store 即使附檔名一樣為 pfx,還是不能在 IE 匯入憑證,但我們可以用 keytool -exportcert 輕易地抽出憑證(不含金鑰)到另一個檔案,再匯入 IE。

Tomcat Connector and IIS 7.5

為了想在 IIS 環境下也能執行 Java Servlet,除了 JDK 與 Servlet Container 本身(我用的是 Tomcat)以外,在 IIS 也要部署一個 ISAPI filter。依官網(http://tomcat.apache.org/connectors-doc/reference/iis.html)的說明,雖然很詳盡了,但由於 IIS 變化太快的關係,到了 7.5 就不容易通,或者變成下載而非執行。以下是幾項特別值得注意的:
  • 修改 Registry 通常是能免則免,所以我選擇編輯一個 isapi_redirect.properties 放在 isapi_redirect.dll 同一目錄下,對此目錄賦予 IUSR 以及 IIS_IUSRS 讀取、執行、列出資料夾內容等權限。
  • 對於放 workers.properties 與 uriworkermap.properties 的目錄,賦予 IIS_IUSRS 讀取權限。
  • 對於放 log 的目錄,賦予 IIS_IUSRS 讀取、寫入權限。
  • 官網說明提到 isapi_redirect.dll 所在要設為虛擬目錄這件事不必做,但在 IIS 管理要新增「處理常式對應」,路徑是「/jakarta/isapi_redirect.dll」,執行檔當然是 isapi_redirect.dll 實際所在的完整路徑。另外,要對此「編輯功能權限」,勾選「執行」。

星期五, 3月 01, 2013

一般使用者權限即可安裝執行的 ActiveX

過去在網頁上部署 ActiveX,都需要電腦使用者具有管理權限才能安裝執行,但據說在 Vista 以後,就鬆綁到一般使用者權限即可。這對於我許多「MIS 管很嚴」的客戶來說,似乎是個蠻不錯(還是剛好相反?)的消息。做為一個 .NET based ActiveX 元件提供者,測試起來的確如此,但其中的小細節還有點多:
  1. 元件一定要經過簽署,而且這與封裝簽署是兩回事。
  2. 如果有被依賴的元件一同部署,不能放到系統目錄。
  3. 封裝資訊指定部署範圍為「使用者」。
  4. [.NET based ActiveX] 不能在封裝內的批次檔呼叫 RegAsm 註冊,要把寫入的所有機碼整理成一個檔案,由批次檔的命令去匯入。
  5. [.NET based ActiveX, Optional] 要請使用者事先加入「信任的網站」,或對「網際網路」安全性區域修改以下兩項:「允許不提示就執行從未使用過的 ActiveX 控制項」為「啟用」、「僅允許認可的網域使用 ActiveX 而不提示」為「停用」。
  6. [Optional] 若能在事前讓簽署元件的憑證位於「受信任的發行者」存放區,且上層憑證皆位於「中繼憑證授權單位」或「受信任的根憑證授權單位」,只要瀏覽器視該網站屬於網際網路(不需加入信任的網站),且安全性設定保持在預設值,元件就能不經提示直接下載安裝。
如果是一個傳統 ActiveX,只要滿足前三點即可。如果是 .NET based ActiveX 又沒做到第五點的話,安裝後的第一次執行會出現一個惱人的資訊列提示,大意是說「這個網站想要執行來自 '無法使用' 的 '控制項名稱無法使用'」,真是亂搞!如果使用者教得好,他願意相信這沒問題的話,倒是無妨。當然,這些雜事(第六點除外)也可以一起併到第四點的機碼匯入,不過安裝完之後還得提醒使用者重啟瀏覽器,如果只是對網頁重新整理的話,那個惱人的資訊列提示還是會出現。

[2013/08/09 補充]
以上第五、六點要多做的事,其實源自於第四點整理的機碼不足。後來找到一個簡單的方法:
  1. 同上
  2. 同上
  3. 同上
  4. RegAsm /regfile:a.reg 將元件的註冊指令先匯出
  5. 修改 a.reg 的內容,指向 HKCR 的改成 HKCU
  6. RegAsm import a.reg
這些步驟可以自動化,而且在 Windows 7, 8, 8.1 測試都沒問題。繁瑣的內容就請容許我保留給公司內訓了。

[2014/10/22 補充]
在 Windows Server 2012 摸索的經驗:
  1. 在伺服器上的瀏覽器限制較嚴格,如果能將網站列入「受信任」區域會好很多。
  2. 預設的 Administrator 首次開啟有 ActiveX 的網頁就是不會提示下載,當然也真的沒有下載。必須另外新增使用者,事後要不要將此人加入管理者群組都可以,反正後續的提示下載安裝 ActiveX 都正常了。

星期四, 2月 07, 2013

將憑證寫入卡片

pkcs11-tool.exe --module 憑證卡驅動程式名 -w 軟體憑證檔路徑 -d 憑證識別碼 -a 憑證標籤 -y cert -l

星期四, 1月 24, 2013

一年只有一天的蘋果線上優惠

好奇怪,MacBook Pro 不管幾吋,是不是配 Retina,全部降 NT$3,120。對於我的目標而言只是九五折,有點失望。

用自然人憑證為程式簽署

憑證相關的工作搞了許久,之前曾掙扎著要不要花錢買個憑證來簽自己想公開的程式。最近靈光一閃,自然就生出這樣的主意,不過沒想到早就有先知了,請參考
http://kmmr.pixnet.net/blog/post/33086772
但還是有一點小小改進:由於我的 signtool.exe 並沒有 signwizard 這個指令,首先關於雙憑證選擇的問題,為了唯一性,必須選 /sha1 再敲一長串雜湊值,有點麻煩。後來摸索出一種做法,先到憑證存放區把加解密用的憑證刪掉,在下指令的時候選 /n 這個參數,帶上憑證主旨,再靠 /a 這個參數讓工具自行判斷最佳值即可。
再來就是像我這種大公司裏的小角色,拿到工商憑證可不容易,試了「測試憑證」也是可以的,不過一定要 2048bits,原因暫時沒有深究。
如果要把這招搬到 Silverlight,效果似乎比較不理想,因為還要補機碼、佈憑證,甚至可以包在 ActiveX 的其他程式庫都要再額外設法放到用戶的電腦上。
順手查了一下目前的作業系統佔比,沒有內建 .NET Framework 的 Windows XP 還有近四成,大概還得再過一兩年才能不為此頭痛。

星期一, 1月 07, 2013

與政府憑證管理中心交手

  • 2012/03/09
    上網填了一張諮詢單(1010302350),指出 HiCOS PKCS#11 2.1.6 + 1024 bits 測試卡簽章會有多了後半段垃圾的問題。
  • 2012/03/15
    獲得回應,將在 2.1.7 版改善,但請自行留意網站上釋出的新版。
  • 2012/04/23
    一直沒看到網站上有新版釋出,再去函詢問,得到另一個諮詢單號(1010404529)。
  • 2012/05/07
    又得到另一個諮詢單號(1010502127),至於什麼事都忘了。
  • 2012/05/09
    2.1.7 版釋出,也有郵件通知。
  • 2012/05/28
    上網填了一張諮詢單(1010510768),指出 HiCOS PKCS#11 2.1.7 + 1024 bits 測試卡解密失敗。當天下午就接到電話告知,轉由某單位處理,網站上此單號直接結案。當天下班前,被轉單位來信要求,用 HiCOS 卡片環境檢測工具確認卡片是否正常?十二分鐘後,回覆檢測一切正常的電子郵件。
  • 2012/05/31
    對方表示查不出問題,要求提供測試程式。
  • 2012/06/01
    提供測試程式與紀錄,對方終於認同這個問題,並表示將釋出新版解決。
  • 2012/09/27
    已過了近四個月還沒見到新版,又發現一個問題,是關於兩張卡一起使用的,只好再去函詢問。當天接獲回覆,新版預計於十月底釋出,並要求新的測試程式。當晚,寄出測試程式。
  • 2012/10/25
    收到「預計釋出的新版」,希望我測試確認無誤。當天回信確認之前提報的問題不再。
  • 2013/01/07
    又過了兩個多月還沒見到新版釋出,再提報未上市的 HiCOS PKCS#11 2.1.8 解密後會有多了一大段填補零的問題,並直接提供測試程式。
  • 2013/01/11
    提報一個問題:在一部電腦上同時接兩個讀卡機,插入 1024 bits 與 2048 bits 的測試卡各一,每次都輸入正確的 Pincode,但可能因憑證卡的位置對調讓登入成功或失敗,並直接提供測試程式。
  • 2013/01/11
    確認一個問題:若 1024 bits 測試憑證上的公、私鑰標籤都不是空白(預設值),雖然申請測試憑證看來沒問題,但無法簽章或解密。原因是在申請測試憑證時,憑證管理中心會尋找卡上可用的金鑰對綁定新憑證,但在上述狀況下並無法挑選到可用的金鑰對,即便如此,該網站還是顯示申請成功。這個不打算回報了,吃力不討好。
  • 2013/03/04
    收到「預計釋出的新版」,希望我測試確認無誤。當天回信確認之前提報的問題不再。