我正在尝试在用户执行请求时在应用程序见解中记录用户名。
我一直试图这样操作:
public class AppInsightsInitializer : ClientIpHeaderTelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public AppInsightsInitializer(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
{
var userName = _httpContextAccessor.HttpContext?.User?.Identity?.Name; // Only set when request failed...
var ip = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
if (userName != null) requestTelemetry.Context.User.AuthenticatedUserId= userName;
}
}
在Startup.cs
中注入并注册电报机之后:
services.AddApplicationInsightsTelemetry(instrumentKey);
services.AddSingleton<ITelemetryInitializer, AppInsights.AppInsightsInitializer>();
但这会导致System.ObjectDisposedException: 'Safe handle has been closed
System.ObjectDisposedException
HResult=0x80131622
Message=Safe handle has been closed
Source=mscorlib
StackTrace:
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Microsoft.Win32.Win32Native.GetTokenInformation(SafeAccessTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength)
at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass)
at System.Security.Principal.WindowsIdentity.get_User()
at System.Security.Principal.WindowsIdentity.GetName()
at System.Security.Principal.WindowsIdentity.get_Name()
at Webeco.Web.AppInsights.AppInsightsInitializer.OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry) in C:\Users\SESEGU\Documents\Projects\AppInsights\AppInsightsInitializer.cs:line 24
at Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers.TelemetryInitializerBase.Initialize(ITelemetry telemetry)
at Microsoft.ApplicationInsights.TelemetryClient.Initialize(ITelemetry telemetry)
然后我尝试了以下代码:
public class AppInsightsInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
var identity = WindowsIdentity.GetCurrent();
if (identity != null)
{
var name = new WindowsPrincipal(identity);
telemetry.Context.User.AuthenticatedUserId = name.Identity.Name;
}
}
}
这在本地计算机上运行良好。但是,当我在开发环境中尝试时,它只会记录服务器名称而不是用户名称。
所以我在想我的第一个解决方案是正确的方法。但是,我无法避免它因Safe handle has been closed
异常而崩溃。
是否有帮助克服这个困难?
答案 0 :(得分:1)
四处逛逛似乎可以解决您的问题
public class AuthenticatedUserIdTelemetryInitializer : ITelemetryInitializer
{
IHttpContextAccessor httpContextAccessor;
public AuthenticatedUserIdTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
if (this.httpContextAccessor?.HttpContext?.User?.Identity?.IsAuthenticated == true)
telemetry.Context.User.AuthenticatedUserId = this.httpContextAccessor.HttpContext.User.Identity.Name;
}
}
这实际上是您的两个示例的组合。
我相信,区别在于使用Initialize
方法而不是重写的OnInitializeTelemetry
方法。
您的httpContextAccessor
可能仍然在Initialize方法中仍然有效,而已被放置在被覆盖的方法中。
不知道从ClientIpHeaderTelemetryInitializer
继承的动机是什么,以及它是否相关。
代码是从here复制的。