SharePoint 列表权限控制
一提到sharepoint 我相信权限控制一定会是一个很重要的话题,尤其是对列表的权限控制,创建、修改、查看权限。其实网上这方面的资料已经很多了,尤其是以下2篇文章,后来索性把CodeArt_PermissionEx的源代码下载下来,然后仔细阅读了以下。
利用开源SharePoint Permission Extension插件对SharePoint 的列表进行权限控制!
要想完全明白源码设计的原理 建议大家先阅读再议WSS RenderingTemplate 对sharepoint模板覆盖有一个简单的了解。我把CodeArt_PermissionEx仔细阅读了一下并且修改了里面的一些代码(个人觉得原作者C#基本功一般,sharepoint方面还是不错,我这里修改的是VS2013版的源码)。修改后部署到sharepoint2013上如图:
内容内型权限设计如图:
这里的PersonType是一个自定义内容内型,每一个内型这里有一个人员和组的权限控制,主要控制user是否可以新建记录,比如user不在PersonType内容内型人员和组里面,那么这个user将不能创建记录,没有权限的user进入后看到的结果如图:
看到这里的新建项目变为不可用了。
这里说说查找权限的方式,首先我们需要的我们的设置保存起来,
1)根据我们的类容类型来找权限设置,如果没有任何权限设置那么我们就直接返回true;
2)如果当前用户是管理员用户直接返回true;
3)在指定的人员里面查找当前user是否存在,存在返回true;
4)指定的组里面是否包含当前user,存在返回true;否则返回false
相关代码如下:
public bool CheckRight(SPUser user, string contentTypeName)
{
ContentTypeCreateSetting set = this.GetContentTypeCreateSetting(contentTypeName); if (set == null)
return true; return set.CanCreate(user);
}
public bool CanCreate(SPUser currentUser)
{
if (currentUser != null && currentUser.IsSiteAdmin) return true; if (String.IsNullOrEmpty(this.SpecialAccounts) && String.IsNullOrEmpty(this.SpecialGroups))
return true; if (currentUser == null)
{
return false;
} bool inAccounts = this.IsInSpecialAccounts(currentUser.LoginName); if (inAccounts)
return true; return this.IsInSpecialGroups(currentUser);
}
}
主要原理是新建列表数据默认用到的是NewMenu类,这里我们开发一个带有权限控制的子类NewMenuWithPermission,主要代码如下:
public class NewMenuWithPermission : NewMenu
{ private ListContentTypesCreateSetting _setting;
bool _settingExist = true ; bool UserHaveRight(string cName)
{
if (!_settingExist)
return true; if (_setting == null)
{
_setting = ListContentTypesCreateSetting.GeSetting(base.List);
_settingExist = _setting != null;
} if (_setting == null)
return true ; return _setting.CheckRight(SPContext.Current.Web.CurrentUser, cName); //return true;
} public override MenuItemTemplate AddMenuItem(string id, string displayName, string imageUrl, string description, string navigateUrl, string onClickScript)
{
MenuItemTemplate m = base.AddMenuItem(id, displayName, imageUrl, description, navigateUrl, onClickScript); m.Visible = this.UserHaveRight(displayName); return m;
} }
如何让sharepoint使用我们这个NewMenuWithPermission类,这里我们需要覆盖sharepoint的DocumentLibraryViewToolBar 和 ViewToolBar模板,相关代码如下:
<SharePoint:RenderingTemplate ID="DocumentLibraryViewToolBar" runat="server">
<Template>
<wssuc:ToolBar CssClass="ms-menutoolbar" EnableViewState="false" id="toolBarTbl" ButtonSeparator="<img src='/_layouts/15/images/blank.gif' alt=''>" RightButtonSeparator=" " runat="server">
<Template_Buttons>
<codeart:NewMenuWithPermission runat="server" AccessKey="<%$Resources:wss,tb_NewMenu_AK%>"/>
<%--<SharePoint:NewMenu ID="NewMenu1" Visible="false" AccessKey="<%$Resources:wss,tb_NewMenu_AK%>" runat="server"/>--%>
<SharePoint:UploadMenu ID="UploadMenu1" AccessKey="<%$Resources:wss,tb_UploadMenu_AK%>" runat="server"/>
<SharePoint:ActionsMenu ID="ActionsMenu1" AccessKey="<%$Resources:wss,tb_ActionsMenu_AK%>" runat="server"/>
<SharePoint:SettingsMenu ID="SettingsMenu1" AccessKey="<%$Resources:wss,tb_SettingsMenu_AK%>" runat="server"/>
</Template_Buttons>
<Template_RightButtons>
<SharePoint:PagingButton ID="PagingButton1" runat="server"/>
<SharePoint:ListViewSelector ID="ListViewSelector1" runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
</Template>
</SharePoint:RenderingTemplate> <SharePoint:RenderingTemplate ID="ViewToolBar" runat="server">
<Template>
<wssuc:ToolBar CssClass="ms-menutoolbar" EnableViewState="false" id="toolBarTbl" ButtonSeparator="<img src='/_layouts/15/images/blank.gif' alt=''>" RightButtonSeparator=" " runat="server">
<Template_Buttons>
<codeart:NewMenuWithPermission runat="server" AccessKey="<%$Resources:wss,tb_NewMenu_AK%>"/>
<%--<SharePoint:NewMenu AccessKey="<%$Resources:wss,tb_NewMenu_AK%>" runat="server" />--%>
<SharePoint:ActionsMenu AccessKey="<%$Resources:wss,tb_ActionsMenu_AK%>" runat="server" />
<SharePoint:SettingsMenu AccessKey="<%$Resources:wss,tb_SettingsMenu_AK%>" runat="server" />
</Template_Buttons>
<Template_RightButtons>
<SharePoint:PagingButton runat="server"/>
<SharePoint:ListViewSelector runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
</Template>
</SharePoint:RenderingTemplate>
现在我们来查看view的权限设计
没有权限的人访问时运行结果如下:
这里的view权限查找方式和控制方式与上面内容内型权限控制都是一样的,下面提到的字段权限设计也是一样的原理。只是这里我们需要开发一个PermissionListViewSelector类来扩展默认的ViewSelectorMenu类,实现代码如下:
public class PermissionListViewSelector : ViewSelectorMenu // Microsoft.SharePoint.WebControls.ListViewSelector
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e); //if (!this.Context.User.Identity.IsAuthenticated)//for anonymous access
//{
// return;
//} var currentUser = base.Web.CurrentUser; if (currentUser != null && currentUser.IsSiteAdmin)
{
return;
} SPList curList = SPContext.Current.List; ListViewPermissionSetting listSetting = ListViewPermissionSetting.GetListSetting(curList);
if (listSetting == null)
{
return;
} if (SPContext.Current.ViewContext == null || SPContext.Current.ViewContext.View == null)
return; SPView currentView = SPContext.Current.ViewContext.View; ViewPermission viewSetting = listSetting.GetByViewID(currentView.ID);
if (viewSetting == null)
return; if (( viewSetting!= null) && (!(viewSetting.CanDisplay(currentUser))))
{
//如果用户没有权限访问当前视图,那么需要计算其有权限访问的试图 if (currentView.DefaultView) //如果访问默认视图而没有权限时,自动转向一个有权限的试图
{
Guid id = listSetting.GetCanDisplayView(currentUser);
if (id == Guid.Empty)
{
SPUtility.TransferToErrorPage(Util.GetResource("Msg_NoViewRight"));
return;
}
else
{
SPView view = curList.Views[id];
SPUtility.Redirect( base.Web.Url +"/"+ view.Url, SPRedirectFlags.Default, this.Context);
return;
}
}
SPUtility.TransferToErrorPage(Util.GetResource("Msg_NoViewRight"));
} //NND, 在2010的07UI模式下这样设置不起作用。
foreach (Control item in base.MenuTemplateControl.Controls)
{
if ((item is MenuItemTemplate))
{
MenuItemTemplate menuItem = (MenuItemTemplate)item; if (menuItem.PermissionsString != "ViewListItems") //修改视图和创建视图菜单
{
menuItem.Visible = false;
continue;
} try
{
SPView tempView = curList.Views[menuItem.Text]; viewSetting = listSetting.GetByViewName(menuItem.Text); if (viewSetting == null)
continue; item.Visible = viewSetting.CanDisplay(currentUser);
}
catch (ArgumentException)
{
}
}
}
} }
如何让sharepoint默认使用我们这个PermissionListViewSelector类了,同样我们需要修改ViewSelector模板
<SharePoint:RenderingTemplate ID="ViewSelector" runat="server">
<Template>
<table border= cellpadding= cellspacing= style='margin-right: 4px'>
<tr>
<td nowrap class="ms-listheaderlabel"><SharePoint:EncodedLiteral ID="EncodedLiteral1" runat="server" text="<%$Resources:wss,view_selector_view%>" EncodeMethod='HtmlEncode'/> </td>
<td nowrap class="ms-viewselector" id="onetViewSelector" onmouseover="this.className='ms-viewselectorhover'" onmouseout="this.className='ms-viewselector'" runat="server">
<codeArt:PermissionListViewSelector MenuAlignment="Right" AlignToParent="true" runat="server" id="ViewSelectorMenu" />
</td>
</tr>
</table>
</Template>
</SharePoint:RenderingTemplate>
最后我们来看看字段权限设置
这里权限设置分为编辑和查看权限,没有编辑权限的用户如下图:
结合权限设置的那张图看一看,这里只有Middle Name字段可以编辑,其他所有字段都不能编辑,Middle Name是允许”ALL User“编辑的,所以这里user可以编辑。查看权限也是一样的。
这里我们需要开发一个EditControlListFieldIterator类来扩展默认的ListFieldIterator类,如何让sharepoint来使用我们的这些类,我们需要修改sharepoint的ListForm和FileFormFields模板,相关代码如下:
public class EditControlListFieldIterator : Microsoft.SharePoint.WebControls.ListFieldIterator
{
protected override void CreateChildControls()
{
//if (this.ControlMode == SPControlMode.Display)
//{
// base.CreateChildControls();
// return;
//} SPUser currentUser = SPContext.Current.Web.CurrentUser; if (currentUser != null && currentUser.IsSiteAdmin)
{
base.CreateChildControls();
return;
} ListFieldPermissionSetting listSetting = ListFieldPermissionSetting.GetListSetting(this.List);
if (listSetting == null || listSetting.Count == )
{
base.CreateChildControls();
return;
} //base.CreateChildControls();
this.Controls.Clear();
if (this.ControlTemplate == null)
{
throw new ArgumentException("Could not find ListFieldIterator control template.");
} Type t = typeof(TemplateContainer); PropertyInfo ControlModeProp = t.GetProperty("ControlMode", BindingFlags.Instance | BindingFlags.NonPublic);
PropertyInfo FieldNameProp = t.GetProperty("FieldName", BindingFlags.Instance | BindingFlags.NonPublic); SPUser author = null; if (this.ControlMode == SPControlMode.New)
{
author = base.Web.CurrentUser; for (int i = ; i < base.Fields.Count; i++)
{
SPField field = base.Fields[i]; if (!this.IsFieldExcluded(field))
{
FieldPermission set = listSetting.GetByFieldName(field.InternalName); if (set != null && !set.CanEdit(currentUser, author))
{
continue;
} TemplateContainer child = new TemplateContainer();
this.Controls.Add(child);
FieldNameProp.SetValue(child, field.InternalName, null);
this.ControlTemplate.InstantiateIn(child);
}
} }
else
{
SPFieldUserValue authorFieldValue = new SPFieldUserValue(base.Web, "" + this.ListItem["Author"]);
author = authorFieldValue.User; for (int i = ; i < base.Fields.Count; i++)
{
SPField field = base.Fields[i]; if (!this.IsFieldExcluded(field))
{
SPControlMode thisMode = this.ControlMode; FieldPermission set = listSetting.GetByFieldName(field.InternalName); if (set != null )
{
if (!set.CanEdit(currentUser, author))
{
if (set.CanDisplay(currentUser, author))
thisMode = SPControlMode.Display;
else
continue;
}
} TemplateContainer child = new TemplateContainer();
this.Controls.Add(child);
FieldNameProp.SetValue(child, field.InternalName, null);
ControlModeProp.SetValue(child, thisMode , null);
this.ControlTemplate.InstantiateIn(child); }
} } } }
<SharePoint:RenderingTemplate ID="ListForm" runat="server">
<Template>
<SPAN id='part1'> <SharePoint:InformationBar runat="server"/>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator=" " runat="server">
<Template_RightButtons>
<SharePoint:NextPageButton runat="server"/>
<SharePoint:SaveButton runat="server"/>
<SharePoint:GoBackButton runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
<SharePoint:FormToolBar runat="server"/>
<TABLE class="ms-formtable" style="margin-top: 8px;" border= cellpadding= cellspacing= width=%>
<SharePoint:ChangeContentType runat="server"/>
<SharePoint:FolderFormFields runat="server"/> <codeArt:EditControlListFieldIterator runat="server"/> <SharePoint:ApprovalStatus runat="server"/>
<SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>
</TABLE>
<table cellpadding= cellspacing= width=%><tr><td class="ms-formline"><IMG SRC="/_layouts/15/images/blank.gif" width= height= alt=""></td></tr></table>
<TABLE cellpadding= cellspacing= width=% style="padding-top: 7px"><tr><td width=%>
<SharePoint:ItemHiddenVersion runat="server"/>
<SharePoint:ParentInformationField runat="server"/>
<SharePoint:InitContentType runat="server"/>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator=" " runat="server">
<Template_Buttons>
<SharePoint:CreatedModifiedInfo runat="server"/>
</Template_Buttons>
<Template_RightButtons>
<SharePoint:SaveButton runat="server"/>
<SharePoint:GoBackButton runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
</td></tr></TABLE>
</SPAN> <SharePoint:AttachmentUpload runat="server"/>
<hr/>
</Template>
</SharePoint:RenderingTemplate> <SharePoint:RenderingTemplate ID="FileFormFields" runat="server">
<Template>
<codeArt:EditControlListFieldIterator runat="server"/>
</Template>
</SharePoint:RenderingTemplate>
这里我们的权限设置都保存到哪里去了?这里默认是把权限设置的object 序列化为字符串然后保存到一个特定的文档库里面去了的。
看到这个图,我想大家应该知道这里的权限设置时怎么保存的了吧,每个list内容内型权限设置、试图权限设置、字段权限设置分别对应一个文件。
为了回报大家,这里特地分享一个知识点;大家在安装sharepoint2013 和 VS2013是 一定要保持语言版本一致,我以前遇到一个 站点模板创建后无法识别的issue,原因就是这2个语言不一致。中文版的sharepoint只能识别2052下的自定义模板,而英文版的VS2013 默认会发布到一个1033的文件夹下,所以中文版的sharepoint2013 默认是不能识别英文版VS2013创建的站点模板。
SharePoint 列表权限控制的更多相关文章
- chmod a+w . 权限控制 su、sudo 修改文件所有者和文件所在组 添加用户到sudoer列表中 当前用户信息
对当前目录对所有用户开放读写权限 chmod a+r . $ sudo chmod -R a+w /usr/lib/python2.7 所有用户添加文件的写权限 [linux]su.sudo.sudo ...
- 【分布式】ZooKeeper权限控制之ACL(Access Control List)访问控制列表
zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:ht ...
- Sharepoint 列表
1.将SharePoint 2010列表数据使用Access打开 在SharePoint 2010新增加了对列表在Access客户端的打开,可以在Microsoft Access 中处理列表中的项目, ...
- 限制用户不能删除SharePoint列表中的条目(项目)
概述 SharePoint列表提供了一个用于在线协作的电子表格,不同的用户可以同时在不同的地方编辑一套数据. 列表功能在收集用户信息.提供审批流程方面为办公人员提供了非常便捷的好处. 既然是协作办公, ...
- 尝试asp.net mvc 基于controller action 方式权限控制方案可行性
微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...
- MongoDB 安全和访问权限控制
MongoDB的访问控制能够有效保证数据库的安全,访问控制是指绑定Application监听的IP地址,设置监听端口,使用账户和密码登录 一,访问控制的参数 1,绑定IP地址 mongod 参数:-- ...
- springmvc+spring+mybatis+maven项目集成shiro进行用户权限控制【转】
项目结构: 1.maven项目的pom中引入shiro所需的jar包依赖关系 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
- 浅谈Yii-admin的权限控制
说到CMS,最需要有的东西就是权限控制,特别是一些复杂的场景,多用户,多角色,多部门,子父级查看等等.最近在开发一个线下销售的东东,这个系统分为管理员端,省代端,客户端,门店端,销售端, 部门端,部门 ...
- Web应用程序系统的多用户权限控制设计及实现-权限模块【10】
前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的权限配置模块.页面模块涉及到的数据表为权限表.权限配置模块是按照用户组和页面,栏目结合组成的.通过配置一个用 ...
随机推荐
- Java虚拟机工作原理简介
1. Java 文件执行过程 2. 运行数据区域 Runtime Data Areas:当运行一个JVM示例时,系统将分配给它一块内存区域(这块内存区域的大小可以设置的),这一内存区域由JVM自己来管 ...
- 洛谷.3835.[模板]可持久化平衡树(fhq treap)
题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...
- 【拓扑排序】BZOJ4010-[HNOI2015]菜肴制作
[题目大意] 是要求N个点的一个拓扑序,且满足以下条件:编号1的位置尽可能靠前,在满足所有限制,编号2的位置尽可能靠前,以此类推. [思路] 一开始觉得优先队列维护一下拓扑就好了.然而样例告诉我们是不 ...
- [CC-XXOR]Chef and Easy Problem
[CC-XXOR]Chef and Easy Problem 题目大意: 给你一个长度为\(n(n\le10^5)\)的序列\(A(A_i<2^{31})\).\(m(m\le10^5)\)次询 ...
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem J. Joke 水题
Problem J. Joke 题目连接: http://codeforces.com/gym/100714 Description The problem is to cut the largest ...
- 简单分享apache封IP的方法
1. 在配置文件里设置: 打开httpd.conf编辑:<Directory “/var/www/html”> Options Indexes FollowSymLinks ...
- java ftp上载下传 遇到的问题
1.下载文件中文乱码,和下载文件大小为0kb /** * Description: 从FTP服务器下载文件 * * @param url * FTP服务器hostname * @param port ...
- javascript区域打印代码
这段代码是我从Highcharts的代码中改造出来的,非常感谢Highcharts的作者,先链上Highcharts的地址http://www.highcharts.com/,(Highcharts的 ...
- 使用p3p跨域设置Cookie
有些时候不能将url上的参数传来传去,比如与调用某开放平台上的接口,这时候可能需要借助Cookie来进行处理了,但这里可能又涉及到跨域的问题. 如果浏览器开启了对Cookie的支持,按照Cookie ...
- 加快Qemu Aarch32虚拟开发板的启动速度
软件版本 Qemu: 2.8.0 虚拟开发板: vexpress-ca9 概述 之前的博文介绍了将Python移植到开发板上, 根文件系统采用的是ramdisk, 这个文件系统的缺点是修改的内容重启会 ...