简体   繁体   English

如何在C#Web API同步和异步中获取Windows身份验证用户

[英]How to get Windows Authenticated user in C# Web API sync and async

I need some helping to solve this issue I'm stuck with at work. 我需要一些帮助才能解决我在工作中遇到的问题。 We have an Web API in .NET Framework 4.7.1 (It has an API, Application, Core, Test projects). 我们在.NET Framework 4.7.1中有一个Web API(它有一个API,应用程序,核心,测试项目)。 The project is complex and it has code from 10+ different developers. 该项目很复杂,它包含来自10多个不同开发人员的代码。 We use Microsoft Dynamics D365 8.2 OnPremise for our data, so anytime we have to do CRUD operations we have to connect with the CRM via their SDK code. 我们使用Microsoft Dynamics D365 8.2 OnPremise来获取数据,因此,只要我们必须进行CRUD操作,我们就必须通过其SDK代码与CRM连接。 The project is hosted on IIS 8.5 Windwos Server 2012 R2 and the front-end is Angular 5 (we use the withCredentials option for API calls). 该项目托管在IIS 8.5 Windwos Server 2012 R2上,前端是Angular 5(我们使用withCredentials选项进行API调用)。 We have Windows Authentication and ASP.NET Impersonation turned on and all other Authetication methods disabled. 我们启用了Windows身份验证和ASP.NET模拟,并禁用了所有其他身份验证方法。 On our C# code, 99% of the times we connect to our CRM SDK we also need to impersonate the user, we do this by passing the username to get a Guid. 在我们的C#代码中,99%的时候我们连接到CRM SDK,我们还需要冒充用户,我们通过传递用户名来获取Guid。 This code has been working for a long time, until very recently we found out our code was setting the user incorrectly randomly. 此代码已经工作了很长时间,直到最近我们发现我们的代码是错误地随机设置用户。

The code that sometimes doesn't work is: 有时不起作用的代码是:

System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()).Identity.Name

Most of the times we get the correct user but sometimes it gets the user running the process in IIS. 大多数情况下,我们获得了正确的用户,但有时它会让用户在IIS中运行该进程。

I also tried: 我也尝试过:

System.Web.HttpContext.Current.User.Identity.Name

But sometimes this is null 但有时这是空的

And lastly what I thought the solution was: 最后我认为解决方案是:

System.Threading.Thread.CurrentPrincipal.Identity.Name

This worked for many of my tests. 这适用于我的许多测试。 The problem is, after a while (I think if the service gets called inside a Task.Run(() => {}); block it gives an error: System.ObjectDisposedException: Safe handle has been closed 问题是,过了一会儿(我想如果服务在Task.Run(()=> {}内调用);阻止它会产生错误:System.ObjectDisposedException:安全句柄已关闭

I read the following articles to help: official Documentation about .net web api: https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api 我阅读了以下文章以获得帮助:关于.net web api的官方文档: https//docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-网络API

This post talking about a very similar issue: https://social.msdn.microsoft.com/Forums/vstudio/en-US/bca4556e-53f3-427c-a51a-9b955e2395e2/how-to-get-the-windows-identity-through-web-api-2-in-a-intranetlocal-network-setup?forum=wcf#89485c63-352b-434a-862b-8c5f4cec620c 这篇文章谈到一个非常类似的问题: https//social.msdn.microsoft.com/Forums/vstudio/en-US/bca4556e-53f3-427c-a51a-9b955e2395e2/how-to-get-the-windows-identity -通过Web方式的API-2-IN-A-intranetlocal -网络设置?论坛= WCF#89485c63-352b-434A-862B-8c5f4cec620c

These two post about the Safe Handle has been closed: Retaining principal inside queued background work item Set Thread.CurrentPrincipal Asynchronously? 关于安全句柄的这两篇帖子已经关闭: 在校对后台工作项中保留主体 设置Thread.CurrentPrincipal异步?

which made me try to write some code like (kept the System.Threading.Thread.CurrentPrincipal.Identity.Name working but still throwing the error): 这使我尝试编写一些代码(保持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);
    });

Any ideas or suggestions about this would be great. 任何有关这方面的想法或建议都会很棒。 Maybe I need something more complex like creating a custom Principal or maybe I'm just messing up the Task.Run (which I finally thought I had it figured out...) 也许我需要一些更复杂的东西,比如创建一个自定义的Principal,或者我只是弄乱了Task.Run(我终于认为我弄明白了......)

Thanks! 谢谢!

What I learned is that getting the logged on user in async methods can be pretty tricky. 我学到的是用异步方法获取登录用户可能非常棘手。 The HttpContext is pretty reliable for sync code and when I absolutely need the logged in user I just pass a variable into my async code. HttpContext对于同步代码非常可靠,当我绝对需要登录用户时,我只是将一个变量传递给我的异步代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在C#中模拟没有密码的Windows身份验证登录用户 - How to impersonate windows authenticated login user without password in c# 如何在Web API 2中检查用户是否已通过身份验证 - How to check if user is authenticated in Web API 2 c# .net Web Api Windows 和匿名身份验证获取当前用户 - c# .net Web Api Windows and Anonymous Authentication get current user Web呼叫的C#异步/同步版本返回不同的类型 - C# async/sync versions of Web Call return different types 如何从内部ASP Web应用程序获取Windows身份验证的用户GUID? - how to get windows authenticated user guid from internal asp web application? 用户通过身份验证后触发事件-Windows身份验证C# - Fire event after user is authenticated - windows authentication c# 从.Net Web API中经过Azure身份验证的AD获取用户名 - Get user name from Azure authenticated AD in .Net Web API 如何从 asp.net web api 中的身份声明获取 JWT 身份验证的登录用户 - How to get JWT authenticated sign-in user from identity claims in asp.net web api 获取经过身份验证的Windows用户的名称 - Get name of authenticated windows user 我在IIS上托管了Windows经过身份验证的HTML页面。 如何使用C#代码获取LoginID - I have a windows authenticated HTML page hosted on IIS. How to get LoginID using C# code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM