4 votes

Application Insights ajoute le nom d'utilisateur à la télémétrie

J'essaie d'enregistrer les noms d'utilisateur des utilisateurs dans Application Insights lorsqu'ils effectuent des requêtes.

J'ai essayé de le faire de cette manière :

 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;
        }
    }

Après l'injection et l'enregistrement de la télémétrie dans l'application Startup.cs :

 services.AddApplicationInsightsTelemetry(instrumentKey);
 services.AddSingleton<ITelemetryInitializer, AppInsights.AppInsightsInitializer>();

Mais celui-ci a pour résultat 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)

Puis j'ai essayé le code ci-dessous :

 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;
            }
        }
    }

Cela fonctionne bien sur une machine locale. Mais lorsque je l'essaie dans un environnement de développement, il n'enregistre que le nom du serveur au lieu du nom de l'utilisateur.

Je pense donc que ma première solution est la bonne. Cependant, je ne parviens pas à éviter le plantage avec la fonction Safe handle has been closed exception.

Vous pouvez m'aider à surmonter cette épreuve ?

2voto

Nesaje Points 306

Après avoir cherché un peu, il semble que cela puisse résoudre votre problème.

    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;
        }
    }

C'est vraiment une combinaison de vos deux exemples. Je crois que la différence réside dans l'utilisation de Initialize au lieu de la méthode surchargée OnInitializeTelemetry méthode. Il se peut que votre httpContextAccessor est toujours en vie dans la méthode Initialize, alors qu'il est déjà éliminé dans la méthode surchargée. Je ne suis pas sûr de la motivation pour hériter de ClientIpHeaderTelemetryInitializer et si c'est pertinent.

Le code est copié de aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X