rest - 带有不记名令牌的 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 在那里,一段时间后它不是......
解决方案
我找到了解决方法。不是很好,但我现在看不到任何其他选择。我们已经开始声明对 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 秒内正确响应我们。
推荐阅读
- python-3.x - pyramid-arima auto_arima 顺序选择
- spring - 使用 WebFlux 框架的设计是否正确?
- javascript - 如何在不更新版本的情况下更新 npm 包自述文件?
- vuepress - 在 vuepress 中更改 404 页面
- thymeleaf - 如何防止 th:onclick 中的单引号在使用 thymeleaf 时被转义
- java - 为什么我得到 Ja.lang.StackOverflowError
- qt - 将 QVector 属性暴露给 D-Bus
- arrays - 如何处理“索引超出范围”Swift 4
- javascript - 选择选项不起作用Vue js
- logging - Kubernetes:如何将容器日志文件挂载到主机