zoukankan      html  css  js  c++  java
  • SharePoint 列表权限控制

    一提到sharepoint 我相信权限控制一定会是一个很重要的话题,尤其是对列表的权限控制,创建、修改、查看权限。其实网上这方面的资料已经很多了,尤其是以下2篇文章,后来索性把CodeArt_PermissionEx的源代码下载下来,然后仔细阅读了以下。

    利用开源SharePoint Permission Extension插件对SharePoint 的列表进行权限控制!

    通过代码解决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);
            }
        }
    View Code

    主要原理是新建列表数据默认用到的是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;
            }
    
             
        }
    View Code

    如何让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 Code

    现在我们来查看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)
                        {
                        }
                    }
                }
            }
     
         
        }
    View Code

    如何让sharepoint默认使用我们这个PermissionListViewSelector类了,同样我们需要修改ViewSelector模板

    <SharePoint:RenderingTemplate ID="ViewSelector" runat="server">
        <Template>
            <table border=0 cellpadding=0 cellspacing=0 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>
    View Code

     最后我们来看看字段权限设置

    这里权限设置分为编辑和查看权限,没有编辑权限的用户如下图:

    结合权限设置的那张图看一看,这里只有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 == 0)
                {
                    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 = 0; 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 = 0; 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);
    
                        }
                    }
    
                }
    
            }
    
    
        }
    View Code
    <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=0 cellpadding=0 cellspacing=0 width=100%>
                <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=0 cellspacing=0 width=100%><tr><td class="ms-formline"><IMG SRC="/_layouts/15/images/blank.gif" width=1 height=1 alt=""></td></tr></table>
                <TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px"><tr><td width=100%>
                <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>
    View Code

     这里我们的权限设置都保存到哪里去了?这里默认是把权限设置的object 序列化为字符串然后保存到一个特定的文档库里面去了的。

    看到这个图,我想大家应该知道这里的权限设置时怎么保存的了吧,每个list内容内型权限设置、试图权限设置、字段权限设置分别对应一个文件

    源码下载

    为了回报大家,这里特地分享一个知识点;大家在安装sharepoint2013 和 VS2013是 一定要保持语言版本一致,我以前遇到一个 站点模板创建后无法识别的issue,原因就是这2个语言不一致。中文版的sharepoint只能识别2052下的自定义模板,而英文版的VS2013 默认会发布到一个1033的文件夹下,所以中文版的sharepoint2013 默认是不能识别英文版VS2013创建的站点模板。

  • 相关阅读:
    [CareerCup] 8.1 Implement Blackjack 实现21点纸牌
    [LeetCode] H-Index 求H指数
    [CareerCup] 7.7 The Number with Only Prime Factors 只有质数因子的数字
    [CareerCup] 7.6 The Line Passes the Most Number of Points 经过最多点的直线
    Ionic实战一:Ionic仿照微信项目
    ionic3+angular4+cordova 项目实例
    Android 给EditText添加下划线
    浅谈移动优先的跨终端Web 解决方案
    Android环信即时通讯集成坑爹 注册报错208解决
    Android自定义控件 -- 带边框的TextView
  • 原文地址:https://www.cnblogs.com/majiang/p/3627124.html
Copyright © 2011-2022 走看看