Gravatar for mcandrew@rdacorp.com

Question by Ken McAndrew, Jan 23, 2018 1:52 PM

Secured item does not show for authorized users

This is using Sitecore 8.1 Update 1, Coveo on-premises version 7 (8388.7) free edition, and Coveo for Sitecore version 4.0.222.0.

I have a document that's been secured such that everyone is denied access to it in inheritance, but then certain groups are granted read permissions, so that only those in the specified groups can see the content. Looking at the Effective Combined Permissions list for my item in the index browser, if I search for my account I see that it is marked as Allowed, so I'd expect to see the content in my search results. However, when I perform a search, the content isn't visible in the results.

The only advanced expression I have in the query is that it needs to have a layout, be part of a particular site, or it needs to be in a particular path. In this case, the path qualifier comes in as well as having a layout. So nothing is immediately jumping out as to why my content wouldn't appear on the site. I can browse to the content just fine.

In my Sitecore logs, I do find the following error multiple times, for user accounts I know to exist...this is a good example. I'm not sure if this error could be a reason the security isn't being honored correctly.

10804 00:00:51 ERROR An error occurred while calling method "GetUserMembers".
Exception: Coveo.Connectors.Sitecore2.SitecoreWebServiceExceptions.SitecoreWebServiceUserNotFoundException
Message: The user "xyz\anonymous" does not exist.
Source: Coveo.Connectors.Sitecore2.SitecoreWebService
   at Coveo.Connectors.Sitecore2.SitecoreWebService.Wrapper.BaseSitecoreWrapper.GetUserMembers(String p_UserName)
   at Coveo.Connectors.Sitecore2.SitecoreWebService.SitecoreWebService.<>c__DisplayClass1d.<GetUserMembers>b__1c()
   at Coveo.Connectors.Sitecore2.SitecoreWebService.SitecoreWebService.TryCatchWrapper[T](Func`1 p_Action, String p_MethodName)

The Coveo diagnostic page shows all green, except for the Coveo Search Web Service, which presents this error. I don't know if there's a possible correlation here.

System.ArgumentException:Invalid JSON primitive:.
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input,Int32 depthLimit,JavaScriptSerializer serializer)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer,String input,Type type,Int32 depthLimit)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)
   at Coveo.Framework.Utils.JsonSerializer.DeserializeObjectFromString[T](String pString)
   at Coveo.SearchServiceProvider.Rest.ResponseParser.ParseQueryResults(String pJsonResponse)
   at Coveo.SearchServiceProvider.Rest.ClientSessionWrapper.ExecuteQuery(QueryParams pQueryParams)
   at Coveo.SearchProvider.Applications.OnPremiseStateVerifier.VerifySearchService()
   at Coveo.SearchProvider.Applications.OnPremiseStateVerifier.<>cDisplayClass14.<GetSearchServiceState>b13()
   at Coveo.SearchProvider.Applications.BaseVerifier.VerifyComponent(Func`1 pVerifyMethod, String p_ComponentName)

Gravatar for dberube@coveo.com

Comment by Dominic Berube, Jan 23, 2018 1:58 PM

The error that says that a user does not exist is indeed the reason why you can't see your items. This error should only shows up when the user is really missing, but if you can validate that it exist, I don't see why you are getting it.

Also, 4.0.222.0 is a really old version and you should upgrade :-)

Gravatar for mcandrew@rdacorp.com

Comment by Ken McAndrew, Jan 23, 2018 3:45 PM

I think I've found the problem, but I'm not sure what the best resolution is. This client came to use using an external membership database (it was a transition from Sharepoint and customized on top of that), so we added membership and roles providers in the Sitecore web.config and connected the provider to the "switcher" so that all of the custom domain accounts would go to the custom database. What it looks like is happening, however, is that Coveo is only looking at the membership tables in the Sitecore core database.

Short of manually merging the two databases and getting everything into the core database, is there any way to resolve this? I tried creating a new security provider, but it looks like you can only assign one provider per index.

Gravatar for mcandrew@rdacorp.com

Comment by Ken McAndrew, Jan 25, 2018 3:22 AM

Okay, so I went back in and unhooked my custom membership database in my local environment, so that the Sitecore "standard" would take effect. I created my test account again, and then secured an item so that Everyone was denied inheritance and my test account was granted Read permissions. When I look in Sitecore, my test account has permissions, and when I look up the item in the Coveo index browser, it says the account had permissions as well.

Also, now when I click the account name in the effective permissions section, I'm taken to the Security Browser and I get security information for the test account. Despite this, however, when I log in with my test account, my Coveo results don't return the item in question. If I remove the restrictions and republish the item, it comes back.

I've also been using the "update cache now" link under Content Security in the Coveo admin, but it's still giving me the original error for a ton of accounts that now aren't connected up in the user manager. I've hit it several times, and tried the "clear external security cache now" link, but it's still not recognizing those accounts aren't there anymore and removing them from the cache, it seems.

So it now seems like everything is set up "Sitecore standard" as far as security goes, but the security is still not being recognized. Do I need to pass in the context user to the Coveo query call somehow, like I do the site name or the path I want to limit results to?

Gravatar for mcandrew@rdacorp.com

Comment by Ken McAndrew, Feb 7, 2018 12:25 AM

I thought I'd note, I found the reason behind the problem and a fix, which is particular to our situation, but the information I found during the research I think would be generally beneficial. I'll write it up as an answer to this to share in the near future.

1 Reply
Gravatar for mcandrew@rdacorp.com

Answer by Ken McAndrew, Feb 7, 2018 7:31 PM

The answer turned out to be in the way Sitecore manages users, even if you're using an external membership database. Let's say you have a standard membership and roles database set up, with Sitecore configured to connect a custom domain and its users/roles to it. When you create a user, you'll find the record in the aspnet_Users/aspnet_Membership tables of your external database.

What Sitecore also does, however, is to create a record in the aspnet_Users table of the Core database. The user ID doesn't match (or have to), just the username is present with the domain (even if, in your external membership configuration, you specified to not store the domain with the username). This "marker" record is the key; without it, Coveo will throw those errors about not finding a user. (Also without it, setting security on a Sitecore item with an individual user won't work properly, though role-based security will.)

One thing I was doing was using a membership/role provider specifying the custom provider name. This is NOT necessary; use the standard provider calls and Sitecore will organize things correctly in the background. Since we migrated this external database from another application, we had to manually insert the "marker" records into the Core database. After doing that and clearing up the Coveo security cache, everything was good to go.

Ask a question