SharePoint Secure Store Service 在實際案例中的應用
文章目錄:
之前有一篇博客講到使用EMSManagedAPI操作Exchange郵箱,在實際SharePoint開發中,用戶總是會要求在SharePoint中集成現有exchange郵件系統。在集成的過程中,如何讀取、新建、更改郵件(任務、會議)是首先要解決的問題,接下來要解決的是如何通過用戶驗證,也就是我們經常講到的單點登陸。由於owa采用表單驗證的方式,且沒有找到很好的SharePoint單點登陸有效方案,所以采用了SharePoint2010以后引入的SSS(Secure Store Service),07版本是SSO。下面就來介紹一下SharePoint Secure Store Service 在實際案例中的應用。
Secure Store Service 是SharePoint Server提供的運行在應用程序服務器上的授權服務。Secure Store Service將用戶憑據存儲於一個憑據的數據庫,錄入用戶信息時,會使用密鑰加密。用戶憑據通常包含用戶名和密碼,也可以根據需要包含其他屬性。通過獲取Secure Store Service存儲的憑據,可以用於訪問其他外部應用。根據微軟官方的描述,在SharePoint應用Secure Store Service的解決方案包括:
- Excel Services 可使用安全存儲提供對已發布工作簿中的外部數據源的訪問。這可以用作將用戶憑據傳遞給數據源(此過程通常需要配置 Kerberos 委托)的替代方式。如果您需要為數據身份驗證配置無人參與服務帳戶,則 Excel Services 需要安全存儲。
-
Visio Services 可使用安全存儲提供對已發布的數據連接圖表中的外部數據源的訪問。這可以用作將用戶憑據傳遞給數據源(此過程通常需要配置 Kerberos 委托)的替代方式。如果您需要為數據身份驗證配置無人參與服務帳戶,則 Visio Services 需要安全存儲。
-
PerformancePoint Services 可使用安全存儲提供對外部數據源的訪問。如果您需要為數據身份驗證配置無人參與服務帳戶,則 PerformancePoint Services 需要安全存儲。
-
PowerPivot 需要安全存儲以便對 PowerPivot 工作簿進行計划刷新。
-
Microsoft Business Connectivity Services 可使用安全存儲將用戶憑據映射到外部系統中的一組憑據。您可將每個用戶的憑據映射到外部系統中的唯一帳戶,也可以將一組經過身份驗證的用戶映射到單個組帳戶。Business Connectivity Services 還可以使用安全存儲來存儲用於訪問 SharePoint Online 中的本地數據源的憑據。
-
SharePoint 運行時可使用安全存儲來存儲與 Azure 服務進行通信所必需的憑據(如果任何用戶應用程序需要 SharePoint 運行時來設置和使用 Azure 服務)。
本文是除以上解決方案中的另外一種應用。
在使用Secure Store Service前,我們做一些設置。
一、首先,打開SharePoint管理中心,進入應用程序管理,點擊“管理服務應用程序”
在服務應用程序列表中,找到Secure Store Service服務。該服務會在運行配置向導過程中默認配置,也可以點擊新建手動配置(手動配置方法請看官方文檔)。
二、點擊進入Secure Store Service服務
1、首次配置,要生成新密鑰
2、生成新密鑰后,就可以新建目標應用程序,點擊新建
3、進入新建頁面后,填寫相關內容
顯示名稱:目標應用程序顯示名稱
聯系人email:填寫管理員email,用來用戶聯系管理員;
目標應用程序類型:根據需要選擇類型,比如“個人”用來存儲個人憑據,“組”用來存儲組憑據(一個用戶組用一個憑據)
目標應用程序頁 URL:一般選擇默認頁,系統會有一個默認頁面(http:/<samplesite>/_layouts/SecureStoreSetCredentials.aspx?TargetAppId=<TargetApplicationID>)用來錄入用戶憑據。
4、點擊下一步,進入配置字段頁面,按照需要添加憑據需要包含的字段(注:以后不能編輯字段名稱和字段類型)
在這里,我除默認的用戶名和密碼外,另外添加一列EmailAddress用來存儲用戶郵箱,類型選擇一般(Genetic)。
5、繼續點擊下一步
添加目標應用程序管理員,點擊完成,完成創建目標應用程序
至此我們已經完成了Secure Store Service的准備工作,接下來就是實際應用的實踐。
一、用戶憑據錄入
你可以使用系統默認的頁面(http:/<samplesite>/_layouts/SecureStoreSetCredentials.aspx?TargetAppId=<TargetApplicationID>)用於用戶憑據錄入,也可以使用自定義的頁面創建、更新用戶憑據。下面的代碼用來更新(創建)當前用戶的特定目標應用程序憑據:
public static void SetCredentials(string appId, string[] userInfo) { List<SecureStoreCredential> creds = new List<SecureStoreCredential>(); SecureStoreCredential name = new SecureStoreCredential(toSecureString(userInfo[0]), SecureStoreCredentialType.WindowsUserName); SecureStoreCredential pwd = new SecureStoreCredential(toSecureString(userInfo[1]), SecureStoreCredentialType.WindowsPassword); SecureStoreCredential EmailAddress = new SecureStoreCredential(toSecureString(userInfo[2]), SecureStoreCredentialType.Generic); creds.Add(name); creds.Add(pwd); creds.Add(EmailAddress); SecureStoreCredentialCollection credes = new SecureStoreCredentialCollection(creds.ToArray()); SecureStoreServiceProxy proxySs = new SecureStoreServiceProxy(); SPSite site = null; SPWeb web = null; SPSecurity.RunWithElevatedPrivileges(delegate() { site = SPContext.Current.Site; web = SPContext.Current.Web; }); site.AllowUnsafeUpdates = true; web.AllowUnsafeUpdates = true; SPServiceContext context = SPServiceContext.GetContext(site); ISecureStore store = proxySs.GetSecureStore(context); store.SetCredentials(appId, credes); web.AllowUnsafeUpdates = false; site.AllowUnsafeUpdates = false; }
參數介紹:
appid:目標應用程序ID,也就是上面步驟新建的“FirstID”;
userInfo:從頁面中獲取的用戶信息列表;
方法介紹:
1、創建字段實例(注:實例名稱與實際目標應用程序字段名稱沒有關聯,只要順序對就可以了,當然類型要一致)
SecureStoreCredential name = new SecureStoreCredential(toSecureString(userInfo[0]), SecureStoreCredentialType.WindowsUserName);
上面這句語句是創建一個憑據字段,對應FirstID中的“Windows用戶名”,此類型包含一個2個參數的構造函數(字段值,字段類型);
2、創建Secure Store Service代理,獲取當前SharePoint Secure Store Service上下文環境
3、為site,web提升權限
SPSecurity.RunWithElevatedPrivileges(delegate()
{
site = SPContext.Current.Site;
web = SPContext.Current.Web;
});
4、使用ISecureStore的SetCredentials方法更新(創建)用戶憑據。
5、最后,會注意到有一個toSecureString方法,這個方法是對字符串進行安全編碼,代碼是:

public static System.Security.SecureString toSecureString(string s) { System.Security.SecureString secureString = new System.Security.SecureString(); foreach (Char character in s) { secureString.AppendChar(character); } return secureString; }
利用上面的代碼,就可以為用戶配置目標應用程序的憑據。
二、根據當前用戶獲取該用戶憑據信息
使用上面的方法將用戶憑據錄入后,下一步就是利用Secure Store Service獲取用戶憑據。
在使用EMSManagedAPI操作Exchange郵箱所在的博客中,有一個步驟是需要用戶的賬號和密碼。另外,上面在創建目標應用程序的過程中,多加了一列EmailAddress,這樣我們就可以用EWS Managed API中AutodiscoverUrl方法,而不需要知道具體的郵件服務器服務地址,代碼就可以改為:

原代碼: service.Credentials = new WebCredentials(creds); service.Url = new Uri("https://服務器地址/ews/exchange.asmx"); service.PreAuthenticate = true;

修改后: service.Credentials = new WebCredentials(creds); service.AutodiscoverUrl(EmailAddress); service.PreAuthenticate = true;
上面是對之前應用的一點優化,如果有興趣,可以去看之前的博客。接下來是如何取得用戶憑證的實例。
Secure Store Service不需要指定用戶,會直接根據當前上下文獲得當前登陸用戶,下面是獲取用戶信息列表的方法:
public List<string> GetUserCredentialCollection(string appId, SPServiceContext CurrentContext)//appid is the SSS' ID { List<string> credentialList = new List<string>(); SecureStoreProvider prov = new SecureStoreProvider(); SPServiceContext context = CurrentContext; prov.Context = context; //當前上下文信息,以便從上下文中找到當前登陸用戶 try { SecureStoreCredentialCollection cc = prov.GetCredentials(appId); for (int i = 0; i < cc.Count; i++) { ISecureStoreCredential c = cc[i]; IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(c.Credential); string sDecrypString = System.Runtime.InteropServices.Marshal.PtrToStringUni(ptr); credentialList.Add(sDecrypString); } } catch { } return credentialList; }
其實最重要的是for循環中的方法,根據目標應用程序ID,獲取用戶憑據集合,遍歷用戶憑據字段並存放到List中,之后就可以根據個人需求來利用這些信息。
到這里Secure Store Service的應用基本就結束了,總體來說Secure Store Service有利有弊,對於安全性要求很高的用戶來說,可能並不是一個最佳的選擇。但Secure Store Service得靈活性較好,可以存儲用戶的多個應用程序憑據,對於多個系統集成有很好的兼容性。有興趣的朋友,可以一起討論,這篇博客就先寫到這里了。