在sharepoint中,_layouts下的自定义页面没有特别的权限,只要用户能访问sharepoint站点就可以访问_layouts下的自定义程序页面,现在我们需要给自定义页面做一下权限认证。要求如下:
1)自定义程序页面只为特定的站点服务,如图:
我们的自定义页面只为docs站点服务,只有/docs/_layouts/15/这样的访问路径才是合法的。
2)能访问docs站点的用户不一定就可以访问该页面,所以我们需要给该页面配置一个权限管理的list,如图:
3)有些自定义程序页面比较特殊,比如我们开发一个页面来装在rdl报表,那么这个自定义页面的权限就没有多大的意义了,所以我们给自定义页面加上querystring的识别,如图:同样的一个自定义程序页面querystring不同,可以配置不同的权限
现在来看看我们的实现吧:
protected bool CanAccess
{
get
{
if (SPWebNames != null && SPWebNames.Length > 0)
{
string spwebname = SPContext.Current.Web.Name.ToLower();
bool findwebname = SPWebNames.Any(x => x.ToLower().Equals(spwebname));
if (!findwebname)
{
return false;
}
}
List<string> gpnames = GroupNames;
if (gpnames.Count < 1)
{
return true;
}
else
{
SPUser currentUser = SPContext.Current.Web.CurrentUser;
foreach (string gpname in GroupNames)
{
foreach (SPGroup g in currentUser.Groups)
{
if (g.Name.Trim().Equals(gpname))
{
return true;
}
}
}
return false;
}
}
}
首先看看我们当前的web name是否是在配置的web names,如果不是直接返回为false,如果是就继续检查当前user是否具有指定的权限(当前user是否在指定的组里面)。这个配置我们写在sharepoint list里面,用户第一次访问页面时,我们会往该list插入一条新数据,没有指定特定user group name,然后管理员就可以设置该group names。主要代码如下:
string url = HttpContext.Current.Request.Url.AbsolutePath.ToLower();
if (QueryStringWithPermission)
{
url = HttpContext.Current.Request.Url.PathAndQuery.ToLower() ;
}
string _key = "$LayoutsPageWithPermission$";
.................................................................................................................
lock (_lockObj) //lock to avoid creating more than one cfg list.
{
try
{
list = web.Lists[_key];
}
catch
{
}
if (list == null)
{
web.AllowUnsafeUpdates = true;
Guid listId = web.Lists.Add(_key, "List for config , never delete this list.", SPListTemplateType.GenericList);
list = web.Lists[listId];
SPView view = list.DefaultView;
SPViewFieldCollection viewFields = view.ViewFields;
string fieldname = list.Fields.Add("GroupName", SPFieldType.Text, false);
SPField field = list.Fields.GetFieldByInternalName("GroupName");
viewFields.Add(field);
view.Update();
list.Update();
}
SPListItemCollection listitems = list.Items;
foreach (SPListItem spitem in listitems)
{
if (spitem["Title"].ToString().Equals(url))
{
spem = spitem;
break;
}
}
if (spem == null)
{
web.AllowUnsafeUpdates = true;
SPListItemCollection items = list.Items;
SPListItem item = items.Add();
item["Title"] = url;
item["GroupName"] = string.Empty;
item.Update();
spem = item;
}
..................................................................
List<string> groups = new List<string>();
if (spem["GroupName"] == null)
{
return groups;
}
string str = spem["GroupName"].ToString();
groups.AddRange(str.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries));
return groups;
这里我们首先去读取list,如果该list不存在就创建该list,然后往该list中插入数据,如果list存在那么检查对应的url是否存在不存在 就插入数据,最后返回指定的group names。
最后调用的代码如下:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.SPWebNames = new string[] { "docs" };
this.QueryStringWithPermission = true;
}
运行效果如图:
详细的代码如下:
namespace Microsoft.SharePoint.WebControls { using Microsoft.SharePoint; using Microsoft.SharePoint.WebControls; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; public class LayoutsPageWithPermission : LayoutsPageBase { #region Property private static object _lockObj = new object(); private List<string> GroupNames { get { string url = HttpContext.Current.Request.Url.AbsolutePath.ToLower(); if (QueryStringWithPermission) { url = HttpContext.Current.Request.Url.PathAndQuery.ToLower() ; } string _key = "$LayoutsPageWithPermission$"; SPList list = null; SPSite siteColl = SPContext.Current.Site; SPWeb site = SPContext.Current.Web; SPItem spem = null; SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite edsiteColl = new SPSite(siteColl.ID)) { using (SPWeb web = edsiteColl.OpenWeb(site.ID)) { lock (_lockObj) //lock to avoid creating more than one cfg list. { try { list = web.Lists[_key]; } catch { } if (list == null) { web.AllowUnsafeUpdates = true; Guid listId = web.Lists.Add(_key, "List for config , never delete this list.", SPListTemplateType.GenericList); list = web.Lists[listId]; SPView view = list.DefaultView; SPViewFieldCollection viewFields = view.ViewFields; string fieldname = list.Fields.Add("GroupName", SPFieldType.Text, false); SPField field = list.Fields.GetFieldByInternalName("GroupName"); viewFields.Add(field); view.Update(); list.Update(); } SPListItemCollection listitems = list.Items; foreach (SPListItem spitem in listitems) { if (spitem["Title"].ToString().Equals(url)) { spem = spitem; break; } } if (spem == null) { web.AllowUnsafeUpdates = true; SPListItemCollection items = list.Items; SPListItem item = items.Add(); item["Title"] = url; item["GroupName"] = string.Empty; item.Update(); spem = item; } } } } }); List<string> groups = new List<string>(); if (spem["GroupName"] == null) { return groups; } string str = spem["GroupName"].ToString(); groups.AddRange(str.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries)); return groups; } } protected bool CanAccess { get { if (SPWebNames != null && SPWebNames.Length > 0) { string spwebname = SPContext.Current.Web.Name.ToLower(); bool findwebname = SPWebNames.Any(x => x.ToLower().Equals(spwebname)); if (!findwebname) { return false; } } List<string> gpnames = GroupNames; if (gpnames.Count < 1) { return true; } else { SPUser currentUser = SPContext.Current.Web.CurrentUser; foreach (string gpname in GroupNames) { foreach (SPGroup g in currentUser.Groups) { if (g.Name.Trim().Equals(gpname)) { return true; } } } return false; } } } protected string CurrentUserName { get { string userName = SPContext.Current.Web.CurrentUser.LoginName; if (userName.Contains("|")) { userName = userName.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)[1]; } return userName; } } public bool QueryStringWithPermission { set; get; } public string[] SPWebNames { set; get; } #endregion protected void RedirectAccessDenied() { Uri uri = HttpContext.Current.Request.Url; int index = uri.AbsoluteUri.IndexOf("/_layouts"); string urlprfx = uri.AbsoluteUri.Substring(0, index); string url = urlprfx + "/_layouts/15/AccessDenied.aspx?Source=" + uri.OriginalString; HttpContext.Current.Response.Redirect(url); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!CanAccess) { RedirectAccessDenied(); } } } }