首页 > 解决方案 > 带有不记名令牌的 SharePoint 搜索 REST API 返回错误的项目数

问题描述

我的搜索有一个非常奇怪的问题。我在 https://sonar-sandbox.gredspdev.loc/_api/search/query?querytext='DMSSonarDocId:5042aa1f-b3a4-4577-8e21-8a47ca27c243 OR DMSSonarDocId:1401144b-bd3d-429a-a386-5061ecc714e1'&sourceid='a0f4d450-e701-4f2a-888a-8d871002752d'&trimduplicates=false&rankingmodelid='05289DBE-73E9-4665-BF69-EE68274176EB'&rowlimit=9000&enablestemming=false&enablesorting=false&selectproperties='DMSSonarDocId,<...>'上使用 GET 进行查询

我正在使用为我的用户生成的不记名令牌进行身份验证。此查询返回 7 个项目。然后我用我的用户(NTLM)在我的浏览器中执行相同的 URL,它返回 10 个项目。这还不是全部。我再次为我的用户生成令牌。将其粘贴到上一个带有不记名令牌的 GET 请求中,它返回 10 个项目...我正在等待几秒钟,比如说 30... 再获取一次,我返回了 7 个项目(始终相同)!这是 100% 可复制的。在来自浏览器的另一个 GET 和令牌 10 项的重新生成之后,在同一个令牌 7 项上一段时间后......

更新。我发现 ULS 中的日志有所不同: 工作正常时:

Context has no SMTP/UPN claims. IdentityContext: '{"nameid":"s-1-5-21-2843295230-2675739751-2774624307-1482","nii":"urn:office:idp:activedirectory","upn":"kowalj@spdev.loc","userId":"0#.w|spdev\\kowalj","appliesTo":"https:\/\/sonar-sandbox.spdev.loc\/"}'

不正常工作时:

Context has no SMTP/UPN claims. IdentityContext: '{"nameid":"s-1-5-21-2843295230-2675739751-2774624307-1482","nii":"urn:office:idp:activedirectory","upn":"spdev\\kowalj","userId":"0#.w|spdev\\kowalj","appliesTo":"https:\/\/sonar-sandbox.spdev.loc\/"}'

另一个发现:丢失的项目是那些直接分配给我的项目 - 不是通过我们的自定义索赔提供者解决的组 - 是的,我们有一个自定义索赔提供者可以正常工作很长时间(我们只使用 NTLM 授权)。我们正在发送这些声明:

new Claim[]
{
    new Claim("nameid", sid),
    new Claim("nii", Constants.Auth.Token.IdentityIssuer)
};

另一个发现: 当一切正常时,在某个 REST 代理中的 SP 场解决方案中执行此代码:((ClaimsIdentity)HttpContext.Current.User?.Identity).Claims.FirstOrDefault(c => c.ClaimType.EqualsIgnoreCase(ClaimTypes.Upn))返回 upn。当搜索不起作用时,相同的代码返回 null ......正如我所说,我可以刷新页面,并且在开始时 upn 在那里,一段时间后它不是......

标签: restsharepointbearer-token

解决方案


我找到了解决方法。不是很好,但我现在看不到任何其他选择。我们已经开始声明对 Windows 令牌服务,如果用户对我们的应用程序发出一些请求,我们会(不时)向放置在 SharePoint 场解决方案中的自定义代理发出请求,以通过使用普通 Windows 身份验证来模拟该用户使用 SharePoint:

public void RefreshUpn()
{
    WindowsImpersonationContext _wic = null;
    try
    {
        string login = HttpContext.Current.User.Identity.Name;
        login = login.Substring(login.LastIndexOf('|') + 1);
        string[] loginParts = login.Split('\\');
        string loginForUpnLogon = Culture.Invariant($"{loginParts[1]}@{loginParts[0]}");
        WindowsIdentity wi = S4UClient.UpnLogon(loginForUpnLogon);

        if(wi == null)
        {
            throw new InvalidOperationException(Culture.Invariant($"Could not impersonate user '{HttpContext.Current.User.Identity.Name}'."));
        }

        _wic = wi.Impersonate();

        using (var wc = new WebClient())
        {
            wc.UseDefaultCredentials = true;
            var requestUrl = HttpContext.Current.Request.Url;
            wc.DownloadString(requestUrl.Scheme + "://" + requestUrl.Host + "/_api/web/currentuser");
        }
    }
    finally
    {
        _wic?.Undo();
    }
}

发出此类请求后,SharePoint 会在大约 150 秒内正确响应我们。


推荐阅读