安全返回网站集中符合条件的所有列表
-
09-12-2019 - |
题
我使用以下代码来获取 Web 应用程序网站集中的所有“公告”列表。
不幸的是,有时当前用户没有该站点的权限,页面会因异常而失败,即使在 try 块内也是如此。
为所有用户安全地执行以下操作的正确方法是什么,即使是匿名用户也不会得到任何结果?
static public List<SPListMeta> AllSiteAnnouncementsLists()
{
var returnList = new List<SPListMeta>();
foreach (SPSite oSiteCollection in SPContext.Current.Web.Site.WebApplication.Sites)
{
var collWebs = oSiteCollection.AllWebs;
try
{
foreach (SPWeb oWebsite in collWebs)
{
using (oWebsite)
{
var collSiteLists = oWebsite.GetListsOfType(SPBaseType.GenericList);
returnList.AddRange(from SPList oList in collSiteLists where oList.Title == "Announcements" select new SPListMeta(oList));
}
}
}
catch
{
}
}
return returnList;
}
异常正在触发 foreach (SPWeb oWebsite in collWebs)
解决方案
仅检索数据
如果您只查询这些列表中的项目,请考虑以下两种循环遍历所有内容的替代方案:
如果您可以忍受爬行造成的延迟,请使用搜索来收集项目。
如果不是,并且您处于“正常”情况,即如果用户有权访问任何子网站,那么他也至少有权访问网站集根目录,那么您应该更改代码以仅获取 oSiteCollection.RootWeb 内的 oSiteCollection.RootWeb尝试/捕获然后使用 SPS站点数据查询 查询所有子站的公告列表。
其他访问如果您的用户始终有权访问他们有权访问的网站的父网站,那么您可以访问根网站,然后正如 @SPArchaeographer 提到的那样递归地使用 GetSubwebsForCurrentUser 。
如果访问是“随机”的,那么你需要这样的东西:
// Get login of user in some way
var userLogin = SPContect.CurrentWeb.CurrentUser.LoginName;
// Get ids of all site user has access to
var siteIds = new List<Guid>();
SPSecurity.RunWithElevatedPrivileges(() =>
{
using (var elevatedSiteCollection = new SPSite(oSiteCollection.ID))
{
foreach (SPWeb elevatedSite in elevatedSiteCollection.AllWebs)
{
if(elevatedSite .DoesUserHavePermissions(userLogin, SPBasePermissions.Open))
{
siteIds.Add(elevatedSite.ID);
}
}
}
});
foreach (var id in SiteIds)
{
using (SPWeb oWebsite = oSiteCollection.OpenWeb(id))
{
...
}
}
其他提示
在“使用”网络之前检查用户是否有权访问网络, SPWeb.DoesUserHavePermissions 是你想要的方法。例子 -
if(oWebsite.DoesUserHavePermissions(SPBasePermissions.Open))
using (oWebsite)
{
//code
}
请告诉我是否有效。
从您的评论来看,您的问题似乎在线:
var collWebs = oSiteCollection.AllWebs;
该调用要求用户有权访问您正在枚举的 Web 实例 - 一旦您尝试访问用户无权访问的网站,该调用就会失败。尝试使用 SPWeb.DoesUserHavePermission 等解决方法也是无用的,因为即使在调用之前您也会收到访问被拒绝的异常。
您可以执行以下操作:打开一个您确定用户有权访问的网站(也许是根网站?),然后枚举该网站下的所有网站。您可以使用以下代码行来完成此操作。
SPWebCollection websForCurrentUser = theCurrentSite.OpenWeb().GetSubwebsForCurrentUser();
这里的“theCurrentSite.OpenWeb()”是对 SPSite 实例的 OpenWeb() 方法的调用,以获取您将作为搜索基础的 SPWeb - 请注意,您将需要有权访问该“基础”网站。之后,您只需调用 GetSubwebsForCurrentUser 即可。