8月25日
關(guān)于Windows Sharepoint Server的權(quán)限內(nèi)容分析
首先聲明這個領(lǐng)域小弟也是剛涉足, 經(jīng)驗淺的很. 一些看法和說法都是卑微之語. Windows Sharepoint Server中的權(quán)限(Authorization)設(shè)置是通過中間件角色(Role)來與指定用戶(User)發(fā)生關(guān)系的. 并不如同傳統(tǒng)的直接給予某個用戶相應(yīng)的權(quán)限. 即應(yīng)該通過創(chuàng)建一個角色然后在其中組合不同的權(quán)限最后將一個角色賦予一個用戶. 用戶組的概念也是如此. User/Group -- Role --Authorization
無論當(dāng)你是將一個用戶或者組添加入對于某個列表或者某個文件中獲得相應(yīng)的權(quán)限. 那些關(guān)于用戶和用戶組的信息分配存放在配置數(shù)據(jù)庫的UserInfo和Groups表中. 其中tp_siteId代表了所屬站點的ID, tp_Id則是分配給用戶的ID, Groups的組織方式也基本和UserInfo差不多. Role 即角色表, 存放所創(chuàng)建的角色. RoleAssignment存放角色的分配. 其中的ScopeId 會對應(yīng)Perms表中的ScopeId, 當(dāng)你為一個列表或者某個文件添加權(quán)限時并且不繼承父權(quán)限的時候, 在Perms表中會添加相應(yīng)的新記錄內(nèi)容, 并且創(chuàng)建它的ScopeUrl與ScopeID來標(biāo)識它. 并且與RoleAssignment中的scopeId對應(yīng), 而RoleAssignment中的PrincepalId則存放對應(yīng)的UserInfo中的tp_Id或者Groups中的tp_Id. 兩張表中的tp_Id是不會重復(fù)的. 搞清楚了權(quán)限組合和角色創(chuàng)建與分配是如何組成的. 現(xiàn)在來看一下如何通過Windows Sharepoint Server的對象模型以編程方式解決一些問題. 比如我想通過一個EventHandler當(dāng)用戶上傳某個文件以后讓他選擇相應(yīng)的本地域中已存的AD帳戶.
實現(xiàn)Windows Sharepoint Server的EventHandler有兩種方式(暫時只了解兩種), 一種是實現(xiàn)IListEventSick接口. 這種方式的缺點暫時令我感覺到的是很難做一些更復(fù)雜的操作. 另一種方式是派生相應(yīng)的操作時間類. 如果是一些內(nèi)容則是SPItemEventReceiver. 具體內(nèi)容可以通過Reflector反射Microsoft.Sharepoint.dll了解. 可以重寫其中的實現(xiàn)方法來實現(xiàn)我們需要的功能. 現(xiàn)在要編寫一個添加完Item后執(zhí)行的權(quán)限分配操作. 也就是當(dāng)用戶在文檔中心上傳完一個文件以后, 將一個指定的用戶添加入其中獲得該文件的相應(yīng)權(quán)限.
public override void ItemAdded(SPItemEventProperties properties){}
通過SPItemEventProperties我們可以獲得不少關(guān)于觸發(fā)事件的Item的信息. 如SiteId(站點ID), ListId(列表ID), ListItemId(列表項ID). 比如我要訪問那個剛上傳文檔的對象可以通過以下方式:
SPSite sourceSite = new SPSite(properties.SiteId);
SPWeb sourceWeb = sourceSite.OpenWeb();
SPListItem currentListItem = sourceWeb.Lists[properties.ListTitle].Items.GetItemById(properties.ListItemId);
每個列表條目都提供一個角色分配集合RoleAssignments屬性, 它是一個Collection. 提供基本的操作方法. 利用Add我們則可以添加相應(yīng)的新的RoleAssignment元素.
每個列表條目都提供一個角色分配集合RoleAssignments屬性, 它是一個Collection. 提供基本的操作方法. 利用Add我們則可以添加相應(yīng)的新的RoleAssignment元素.
我們通過建立一個RoleAssignment的實例來添加用戶:
SPRoleAssignment roleAssignment = new SPRoleAssignment(sourceWeb.EnsureUser(SHBEYONDBIT\chujun));
SPRoleDefinition roleDefinition = sourceWeb.RoleDefinitions.GetByType(SPRoleType.Read);
SPRoleType 是一個enum提供默認(rèn)角色級別
SPRoleType.Administrator = 完全控制
SPRoleType.WebDesigner = 設(shè)計
SPRoleType.Contributor = 參與討論
SPRoleType.Reader = 讀取
SPRoleType.Guest = 受限訪問
SPRoleType.None = 僅查看
SPRoleType.WebDesigner = 設(shè)計
SPRoleType.Contributor = 參與討論
SPRoleType.Reader = 讀取
SPRoleType.Guest = 受限訪問
SPRoleType.None = 僅查看
對于我們自己創(chuàng)建的Role則不提供支持. 我們需要通過其它方式來獲得. 通過RoleDefinitionBindings屬性的Add方法我們添加了一個Role給予指定的用戶.
roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
currentListItem.BreakRoleInheritance(false);
BreakRoleInheritance就如同我們手動設(shè)置用戶角色時選擇的是否不在繼承父權(quán)限一樣. 我們不再繼承父權(quán)限. 最后通過currentListItem.RoleAssignments.Add(roleAssignment); 為相應(yīng)列表添加了某個用戶的角色.
在這里有一點令人有些費解, 起初我并非用EnsureUser方法實現(xiàn)用戶添加的, 而是通過SPUserInfo創(chuàng)建一個實例. 將AD帳號的一些信息寫入其中. 然后通過sourceWeb.User.Add方法來實現(xiàn)添加, 可惜屢屢報錯說當(dāng)前狀態(tài)無效. 不知有哪位高人知道為何? 不吝賜教.
現(xiàn)在在來討論關(guān)于如何自定義角色問題. 在Windows Sharepoint Server中提供了相當(dāng)多的權(quán)限. 并且通過SPBasePermissions這個enum來設(shè)定. 其實實現(xiàn)的方式大致應(yīng)該是一個int類型. 然后相應(yīng)的位放置1來確定吧. 即以一個unsigned short為例 00100100可能代表某個Role擁有未知的兩個權(quán)限.
SPRoleDefinition definition = new SPRoleDefinition(); 創(chuàng)建角色定義的實例.
public bool AddSiteRole(string name, string description, params SPBasePermissions[] args){
bool flag = true;
SPRoleDefinition definition = new SPRoleDefinition();
definition.Name = name;
definition.Description = description;
foreach (SPBasePermissions arg in args){
definition.BasePermissions |= arg;
}
try{
_sourceWeb.RoleDefinitions.Add(definition);
}
catch{
flag = false;
}
return flag;
}
bool flag = true;
SPRoleDefinition definition = new SPRoleDefinition();
definition.Name = name;
definition.Description = description;
foreach (SPBasePermissions arg in args){
definition.BasePermissions |= arg;
}
try{
_sourceWeb.RoleDefinitions.Add(definition);
}
catch{
flag = false;
}
return flag;
}
進(jìn)行相應(yīng)位置的|操作就可以分配相應(yīng)的權(quán)限了. 如下:
AddSiteRole("自定義角色1", "自定義角色1", SPBasePermissions.AddAndCustomizePages, SPBasePermissions.AddDelPrivateWebParts, SPBasePermissions.AddListItems, SPBasePermissions.ApplyStyleSheets);
順帶一提, 因為SPUser和SPGroup都派生于SPPrincipal, 而SPRoleAssignment可以接受任何派生與SPPrincipal的類型進(jìn)行添加. 想想之前數(shù)據(jù)表RoleAssignment表中的PrincepalId, 在真挺有邏輯的.
最近有一個項目是針對基于Windows Sharepoint Server, 并利用Microsoft Office Sharepoint Server2007和Design的開發(fā)和部署(其實我對這個項目是頗有微辭的, 首先對于這類技術(shù)的集成還沒有掌握, 項目書上說是配置占70%以上, 其實不然以這樣的要求顯然開發(fā)占了70%以上). 并且我對這種Microsoft極度推崇的技術(shù)也是心存一些不滿的. 首先它的內(nèi)容更廣一些,不僅設(shè)計了Windows WorkFlow Fundation, Web Part, ASP.NET 2.0, CAML, Infopath以及Windows Sharepoint Server等大量內(nèi)容還有許多企業(yè)應(yīng)用的概念. 并與Office系列產(chǎn)品有高度集成. 這對于一個開發(fā)人員來說需要掌握更多的技術(shù)特性. 其實光是精通其中兩樣已經(jīng)是很不容易的一回事了. 基于它的二次開發(fā)難度較大, 并且許多默認(rèn)提供用戶的操作方式都不是傳統(tǒng)的Web用戶操作習(xí)慣. 說穿了只是Microsoft想要捆綁它的一整套產(chǎn)品銷售, 賣給那些政府或者大型企業(yè)而已. 哎! 感嘆做為開發(fā)人員, 不是每個項目都能選擇讓你使用你擅長的喜愛的技術(shù).
不知道有誰會在上傳完文件以后先不跳往那個定義名字和注釋的頁面, 而是跳往我想指定的頁面. 因為在Windows Sharepoint Server的那些上傳之類的都是以做完的模板, 可能有些按鈕時間是自定義的控件. 比如像那些SPWikiButton一類. 以完全將處理方法封裝起來了. 除非直接修改頁面上腳本. 但是這類都是模板無法如同那些其它的Default.aspx或者Default.Master那樣進(jìn)行修改. 而也無法獲得所謂的窗體句柄. 如有實現(xiàn)方式請不吝賜教.