【发布时间】:2019-08-19 20:17:20
【问题描述】:
我需要一些帮助来解决我在工作中遇到的问题。我们在 .NET Framework 4.7.1 中有一个 Web API(它有一个 API、应用程序、核心、测试项目)。该项目很复杂,它有来自 10 多个不同开发人员的代码。我们将 Microsoft Dynamics D365 8.2 OnPremise 用于我们的数据,因此无论何时我们必须进行 CRUD 操作,我们都必须通过他们的 SDK 代码连接到 CRM。该项目托管在 IIS 8.5 Windwos Server 2012 R2 上,前端是 Angular 5(我们使用 withCredentials 选项进行 API 调用)。我们启用了 Windows 身份验证和 ASP.NET 模拟,并禁用了所有其他身份验证方法。在我们的 C# 代码中,99% 的时间我们连接到我们的 CRM SDK 时,我们还需要模拟用户,我们通过传递用户名来获取 Guid 来做到这一点。这段代码已经工作了很长时间,直到最近我们发现我们的代码随机设置了错误的用户。
有时不起作用的代码是:
System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()).Identity.Name
大多数时候我们得到正确的用户,但有时它让用户在 IIS 中运行进程。
我也试过了:
System.Web.HttpContext.Current.User.Identity.Name
但有时这是空的
最后我认为解决方案是:
System.Threading.Thread.CurrentPrincipal.Identity.Name
这适用于我的许多测试。问题是,过了一会儿(我认为如果服务在 Task.Run(() => {}); 块内被调用,它会给出错误:System.ObjectDisposedException:安全句柄已关闭
我阅读了以下文章以提供帮助: .net web api官方文档:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
这两个关于安全手柄的帖子已关闭: Retaining principal inside queued background work item Set Thread.CurrentPrincipal Asynchronously?
这让我尝试编写一些代码,例如(保留 System.Threading.Thread.CurrentPrincipal.Identity.Name 工作但仍然抛出错误):
ClaimsPrincipal principal = new ClaimsPrincipal(Thread.CurrentPrincipal);
// Save Total Payment Stream Payments (Async)
Task.Run(() =>
{
HttpContext.Current.User = new ClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", principal.Identity.Name) }, "auth")));
Thread.CurrentPrincipal = principal;
SaveTotalPaymentStream(opportunityTermId);
});
任何关于此的想法或建议都会很棒。也许我需要一些更复杂的东西,比如创建一个自定义 Principal,或者我只是搞砸了 Task.Run(我终于想明白了……)
谢谢!
【问题讨论】:
标签: c# asp.net asynchronous asp.net-web-api2