最近接到了一個任務。實現公司內部辦公平台(基於SharePoint 2007,Windows整合身份認證)和Mantis Bug管理系統(基於php和Mysql資料庫,開源,Form認證)的單點登陸。本來,Mantis是一個開源的項目,修改一下它的認證方式應該就可以了,網上也有人介紹過關於在php中使用LDAP的經驗,可惜啊,本人不懂php,只會ASP.NET,所以想到的解決方案是利用MOSS的SSO,首先在這一部分我來配置使用MOSS的SSO,在後面的一部分中我將向大家介紹怎麼取得SSO裡存放的Mantis使用者名稱和密碼並類比Post提交。
首先啟動Microsoft Single Sign-on Service服務,該服務預設狀態未啟動。
按右鍵服務—屬性,點擊上方選項卡中的登入,選擇“此賬戶”,輸入管理員的使用者名稱和密碼,
再點擊選項卡中的常規,將啟動類型修改為“自動”,並啟動該服務,可能會提示你新賬戶必須在重啟電腦後才有效,重啟。
接下來我們要配置MOSS的SSO。進入管理中心---操作,點擊安全性配置中下方的“管理單一登入的設定”,在伺服器設定中點擊“管理伺服器設定”,依次在“單一登入管理員賬戶”和“公司專屬應用程式程式定義管理員賬戶”中輸入我們的管理員賬戶和密碼,其他可用預設設定,
確定之後,返回操作介面,在公司專屬應用程式程式定義設定中,點擊“管理公司專屬應用程式程式定義的設定”,點擊“建立項目”,在顯示名稱和應用程式名稱中填入合適的名字,這個應用程式名稱字在第二部分用程式讀SSO中存放的使用者名稱和密碼時會用到,在這兒我填的是mantis,再填入連絡人電子郵件地址,在賬戶類型中,我們選擇個人,可以詳細看一下左側的介紹。點擊確定返回。再次進入操作--管理單一登入介面下,在公司專屬應用程式程式定義設定中,點擊“管理公司專屬應用程式程式定義的帳戶資訊”,選擇相應的公司專屬應用程式程式,在使用者賬戶名稱中,輸入對應的域賬戶,點擊設定,在使用者名稱和密碼中,分別登入第三方系統的使用者名稱和密碼後,點擊確定,可繼續設定域賬戶與第三方系統使用者名稱密碼的對應,或者點擊已完成。
這樣,關於單點登陸的建立配置工作就已經完成了,然後需要取得存放在SSO資料庫中的使用者名稱和密碼,並使用它們進行POST提交登陸。思路是這樣的,在MOSS中建立一個aspx頁面,重寫這個頁面的Page_Load事件,也許你會說,MOSS頁面裡不能使用伺服器端代碼,關於這方面的介紹,請參考我的另兩個文章:為MOSS頁面添加後台代碼的兩種方式(一) 為MOSS頁面添加後台代碼的兩種方式(二),
在Page_Load事件中,只有幾行代碼,根據當前登陸域帳戶去取第三方系統Form認證的使用者名稱和密碼(在我這裡是Mantis),並賦值給這個aspx頁面的使用者名稱和密碼的輸入框中,這兩個是隱藏的,然後再在windows的onload事件中,執行aspx頁面上Form的提交操作。以前看過有人做的OWA訪問郵箱的webpart其實也是這種思路,大家都知道,MOSS內建的那個OWA webpart基本沒有使用價值。
那我們就一步步來。首先建立一個aspx頁面,這個頁面完成類比Post提交的工作,用Designer開啟MOSS網站,測試的時候,我直接在網站的根路徑下建立的這個頁面,需要引用三個命名空間,在aspx頁面頂部我們這樣來寫:
<%@ Page Language="c#" CodePage="936"%>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.Portal" %>
<%@ Import Namespace="Microsoft.SharePoint.Portal.SingleSignon" %>
第一行的CodePage=”936”是一個編碼格式的問題,我在Post到mantis時需要,對你並不一定是必須的。引用之後,我們就可以寫Page_Load事件了,這段代碼我是參考網上一哥們寫的,可以拿去直接使用:
<script type="text/c#" runat="server">
protected void Page_Load(object sender, EventArgs e)
{
IntPtr pUserName = IntPtr.Zero;
IntPtr pPassword = IntPtr.Zero;
ISsoProvider isso = SsoProviderFactory.GetSsoProvider();
SsoCredentials myCreds = isso.GetCredentials("mantis");//第一部分提到的應用程式名稱字,我這是mantis
pUserName = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(myCreds.UserName);
String userName = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pUserName);
pPassword = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(myCreds.Password);
String passWord = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pPassword);
this.username.Value = userName;
this.password.Value = passWord;
}
</script>
其中,username和password是我們頁面上的兩個伺服器端控制項,下面就是我們構建的類比提交的Form:
<form action="要Post的地址" method="POST" name="登陸頁面Form名字 " autocomplete="off">
<input type="hidden" name="return" value="Post成功後的地址">
<input name="username" runat="server" id="username" type="hidden">
<input name="password" runat="server" id="password" type="hidden">
</form>
當然,你可能不知道一個第三方系統Post到哪裡去,我們需要藉助一個IE外掛程式HttpWatch來分析一下,點擊外掛程式的Record,當我們再點登陸的時候,就會看到我們需要的post地址,
第一行就是Post的地址,第二行是在登陸成功後轉至的地址,我們需要的就是這兩個。
然後我們再查看一下頁面的源檔案,找到Form的名字及輸入使用者名稱和密碼的兩個文字框,在Mantis裡是login_form 、username和password,就用這三個名字來分別命名我們頁面上的控制項。
到這裡,我們已經完成了根據當前登陸的域帳戶取得Mantis裡的使用者名稱和密碼,並賦值到頁面中,現在需要做的只是在windows.onload時,將頁面提交出去。
在Form的下面,我們這樣來寫:
<script type="text/javascript">
window.onload=function (){document.login_form.submit();};
</script>
這樣完成之後,當登陸的域使用者開啟上面這個頁面後,頁面會自動找到與該使用者對應的Mantis使用者名稱和密碼,並自動Post提交登陸,從而跳過Mantis的login介面。這樣,我們就利用MOSS的SSO實現了單點登入Mantis。