0

Environment? SharePoint 2013 Enterprise on-prem

What can I do? Everything from client side to full trusted farm solutions.

Business requirement? List the (metadata) of all files of a particular type (content type) spread across multiple site collections. The caveat: These files have to be secured to small groups or in some cases individuals (teamsites & mysites). This is regardless if the user has permissions or not.

So OOTB Search web parts are useless as they do not have an option to ignore security context.

401 or access request is acceptable if the user navigates to the file.

My ideas? I could achieve this relatively straight forward in 2010 using server object model and elevation. However with 2013 search changed a fair bit. Is it still possible? Is this even possible/best approach now?

Edit: updated the business requirements with more detail to better explain the scenario.

7
  • Using a search query and "regardless if the user has permissions or not" are mutually exclusive. Get the business to drop that requirement and you can easily use a search query. Elevation is a poor practice. Planning a security model and designing a solution that uses search is the best approach. – Matthew McDermott Feb 27 '18 at 13:48
  • Elevating the search query has always been possible. The business will not drop the requirement. I have updated the business requirements with more detail to better explain this. Are you able to explain specifically why elevating just the search query is "poor practice"? Please offer an alternative security model. Broad generalizations don't help. – Jay Feb 28 '18 at 22:47
  • I strongly believe that it is a poor practice to say it's OK for people to get an access denied message. Plus, by elevating you are "showing folks items they should not or do not have access to" from a compliance and policy perspective this is something a lawyer should evaluate. What private info is in the snippet? There are two alternatives, the first is easier than the second. 1. Properly secure your content. 2. Provide "public" snippets that link to the private content. – Matthew McDermott Mar 1 '18 at 12:42
  • For an external site, sure 401 isn't good. However I think internally users get the OOTB access request form. Like I said, the content has to be protected, specifically because of legal reasons. However users need to be aware that they exist because they're a resource. Part of the metadata is the contact of who owns & manages the content so users can gain access. Access process is offline and changes depending on the content. Without this list, users are unaware the content exists and staff have significant problems doing their job. This project was launched after one such serious incident. – Jay Mar 1 '18 at 22:51
  • Thank you for the suggestions. 1. Well I'm not sure how we could secure the content any more. It's protected already and has to remain so. Only remaining issue is the discovery. 2. Is in-line with my thoughts for how I can resolve this. Since search does not accommodate a solution. I now have to look to an alternative to search. Such as a constantly updated Catalogue (index) most likely via a workflow... It seems ridiculous that I have to create a separate content type in another list which is public to reference the content already stored in the search index. – Jay Mar 1 '18 at 23:01
0

To build a search powered application and get all results is elevation. You also need to be very careful how you elevate. Specifically:

SPUserToken systemAccountUserToken = SPContext.Current.Site.SystemAccount.UserToken;
HttpContext currentUserContext = HttpContext.Current;
SPSecurity.RunWithElevatedPrivileges(() => {
 using (SPSite elevatedSite = new SPSite(siteId, systemAccountUserToken)) {
HttpRequest httpRequest = new HttpRequest(string.Empty, elevatedSite.RootWeb.Url, string.Empty);
HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
SPControl.SetContextWeb(HttpContext.Current, elevatedSite.RootWeb);
KeywordQuery keywordQuery = new KeywordQuery(elevatedSite);
keywordQuery.QueryText ="SPContentType:\"MYContentType\""
SearchExecutor searchExecutor = new SearchExecutor();
ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);
var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
ResultTable resultTable = resultTables.FirstOrDefault();
DataTable dataTable = resultTable.Table;

// Do stuff with you results

}});
HttpContext.Current = currentUserContext; // Very important to set the context back

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.