NLog 的 ${aspnet-user-identity} 写入是空白?终极解决方案

由于使用了不同的认证方式,可能会导致 NLog 的 ${aspnet-user-identity} 拿不到值,从而写入的是空白,谁知道他里面是怎么解析的呢?之前使用 NLog 的配置可能如下

  <targets async="true">
    <target name="fileTarget" xsi:type="File" fileName="..\logs\${shortdate}.txt"
      layout="${longdate} ${uppercase:${level}} ${aspnet-user-identity} ${aspnet-TraceIdentifier} ${callsite} ${message}"
      archiveFileName="..\logs\${shortdate}.{#}.txt" archiveEvery="Day" archiveNumbering="Rolling"
      maxArchiveFiles="60" concurrentWrites="true" keepFileOpen="false" />
    <!--layout="${longdate} ${aspnet-user-identity} ${ndlc:bottomFrames=0:topFrames=1} ${aspnet-TraceIdentifier:ignoreActivityId=false} ${uppercase:${level}} ${logger} ${message}"-->

    <target name="dbTarget"
            xsi:type="Database"
            dbProvider="sqlserver"
            connectionString="${configsetting:name=ConnectionStrings.Default}"
            keepConnection="true"
            commandType="StoredProcedure"
            commandText="[dbo].[usp_AddLog]">
      <parameter name="@machineName" layout="${machinename}" />
      <parameter name="@logged" layout="${date}" />
      <parameter name="@level" layout="${level}" />
      <parameter name="@username" layout="${aspnet-user-identity}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@callsite" layout="${callsite}" />
      <parameter name="@exception" layout="${exception:tostring}" />
    </target>
  </targets>

一个典型的文本文件和数据库的双写模式,但是很不幸的是 ${aspnet-user-identity} 是空的,比如我之前使用 Azure 的默认登录,${aspnet-user-identity} 是有值的,但是我改成了两个登录方案以后,${aspnet-user-identity} 就成空的了

            app.UseEndpoints(endpoints =>
            {
                ......
                // Add endpoints for login challenges
                endpoints.MapGet("/login-customer", async context =>
                {
                    await context.ChallengeAsync(_customerAuthType, new AuthenticationProperties
                    {
                        RedirectUri = "/"
                    });
                });

                endpoints.MapGet("/login-support-agent", async context =>
                {
                    await context.ChallengeAsync(_supportAgentAuthType, new AuthenticationProperties
                    {
                        RedirectUri = "/"
                    });
                });
                ......
             }

这个时候可以采用中间件的方式来解决,中间件的位置很重要,放在

            app.UseAuthentication();
            app.UseAuthorization(); 

之后,紧挨着

          app.Use(async (context, next) =>
          {
              if (context.User.Identity.IsAuthenticated)
              {
                  // Get the preferred username from claims
                  string userName = context.User.Claims.FirstOrDefault(obj => obj.Type == "preferred_username")?.Value;

                  // Set the user name in the NLog's MappedDiagnosticsLogicalContext
                  if (!string.IsNullOrEmpty(userName))
                  {
                      using (MappedDiagnosticsLogicalContext.SetScoped("userName", userName))
                      {
                          // Call the next middleware
                          await next();
                      }
                  }
                  else
                  {
                      // Preferred username is not found in claims
                      await next();
                  }
              }
              else
              {
                  // User is not authenticated, do nothing
                  await next();
              }
          });

MappedDiagnosticsLogicalContext 就是NLog 的上下文方法,用法可自行查阅,然后把NLog 的配置文件的 ${aspnet-user-identity} 替换成 ${mdlc:userName},修改如下

  <!-- the targets to write to -->
  <targets async="true">
    <target name="fileTarget" xsi:type="File" fileName="..\logs\${shortdate}.txt"
      layout="${longdate} ${uppercase:${level}} ${mdlc:userName} ${aspnet-TraceIdentifier} ${callsite} ${message}"
      archiveFileName="..\logs\${shortdate}.{#}.txt" archiveEvery="Day" archiveNumbering="Rolling"
      maxArchiveFiles="60" concurrentWrites="true" keepFileOpen="false" />
    <!--layout="${longdate} ${aspnet-user-identity} ${ndlc:bottomFrames=0:topFrames=1} ${aspnet-TraceIdentifier:ignoreActivityId=false} ${uppercase:${level}} ${logger} ${message}"-->

    <target name="dbTarget"
            xsi:type="Database"
            dbProvider="sqlserver"
            connectionString="${configsetting:name=ConnectionStrings.Default}"
            keepConnection="true"
            commandType="StoredProcedure"
            commandText="[dbo].[usp_AddLog]">
      <parameter name="@machineName" layout="${machinename}" />
      <parameter name="@logged" layout="${date}" />
      <parameter name="@level" layout="${level}" />
      <parameter name="@username" layout="${mdlc:userName}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@callsite" layout="${callsite}" />
      <parameter name="@exception" layout="${exception:tostring}" />
    </target>
  </targets>

数据插入成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值