当Web应用程序部署到IIS时,如何让当前用户登录EnvironmentUserName而不是“IIS APPPOOL\DefaultAppPool”

问题描述 投票:0回答:1

我有一个基本的 CRUD Web 应用程序,它将用户表单输入保存到数据库中。当前用户 ID 与表单输入一起保存,在本地和 IIS 上都没有任何问题。但是,当我将网站发布到 IIS 后通过 Serilog 将

EnvironmentUserName
保存在日志中时,
EnvironmentUserName
始终保存为“IIS APPPOOL\DefaultAppPool”。当我在本地运行 Web 应用程序时,它会按预期捕获我的用户 ID。

我尝试编写一个自定义丰富器,以使用与检索用户 ID 并使用数据库中的表单输入保存时相同的捕获用户 ID 的逻辑,但结果与

EnvironmentUserName
相同。

我一直在阅读ASP NET Core 应用程序中的模拟,但没有找到可以将其应用于一般日志记录的示例。

当从 IIS 运行 Web 应用程序而不获取“IIS APPOOL\DefaultAppPool”时,如何在日志中包含当前登录用户的 ID?

定制丰富器:

public class CurrentUserEnricher : ILogEventEnricher
{
    static readonly string _currentUser;

    /// <summary>
    /// static constructor to load the environment variable
    /// </summary>
    static CurrentUserEnricher()
    {
        _currentUser = WindowsIdentity.GetCurrent().Name.ToUpper();
    }

    public void Enrich(
        LogEvent logEvent,
        ILogEventPropertyFactory propertyFactory)
    {
        var enrichProperty = propertyFactory
            .CreateProperty(
                "CurrentUser",
                _currentUser);

        logEvent.AddOrUpdateProperty(enrichProperty);
    }
}

这是我的appSettings.config。请注意,在编写自定义丰富器后,我将“CurrentUser”保存为“EnvironmentUserName”。

{
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DuckDatabase": "data source=*****;initial catalog=*****;integrated security=True;TrustServerCertificate=True",
    "GooseDatabase": "data source=*****;initial catalog=*****;integrated security=True;TrustServerCertificate=True"
  },
  "Serilog": {
    "Using": [ "Serilog.Sinks.MSSqlServer", "CustomSerilogEnrichers" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft.AspNetCore": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "ConsultsDatabase",
          "sinkOptionsSection": {
            "tableName": "Logs",
            "schemaName": "dbo",
            "autoCreateSqlTable": false,
            "batchPostingLimit": 1000,
            "period": "0.00:00:30"
          },
          "restrictedToMinimumLevel": "Debug",
          "columnOptionsSection": {
            "addStandardColumns": [ "LogEvent" ],
            "removeStandardColumns": [ "MessageTemplate", "Properties" ],
            "additionalColumns": [
              {
                "ColumnName": "EnvironmentUserName",
                "PropertyName": "CurrentUser",
                "DataType": "varchar",
                "AllowNull": true,
                "DataLength": 50
              },
              {
                "ColumnName": "MachineName",
                "DataType": "varchar",
                "AllowNull": true,
                "DataLength": 50
              },
              {
                "ColumnName": "Application",
                "DataType": "varchar",
                "AllowNull": true,
                "DataLength": 50
              }
            ]
          }
        }
      }
    ],
    "Enrich": [ "WithMachineName", "WithCurrentUser" ],
    "Properties": {
      "Application": "Medical Consults"
    }
  }
}

Program.cs,我在其中设置 Serilog:

using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Server.IIS;
using Serilog;
using System.Security.Principal;
using System.Text;
using System;

var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
        .Build();

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();

try
{
    Log.Information("Starting Medical Consults web application");

    var builder = WebApplication.CreateBuilder(args);

    builder.Host.UseSerilog();

    builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate();

    // Add services to the container.
    builder.Services.AddControllersWithViews()
       .AddMvcOptions(options => options.Filters.Add(new AuthorizeFilter("AllowedRoles")));

    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("AllowedRoles",
            policy => policy.RequireRole("*****"));
    });

    var app = builder.Build();

    app.UseSerilogRequestLogging();

    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

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

    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}

项目规格:

  • 项目类型:ASP.Net Core Web App(模型-视图-控制器)
  • .Net框架:7.0
  • 目标操作系统:Windows

Nuget 包:

  • Microsoft.AspNetCore.Authentication.Negotiate v.7.0.10
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore v.7.0.10
  • Microsoft.EntityFrameworkCore v.7.0.10
  • Microsoft.EntityFrameworkCore.Design v.7.0.10
  • Microsoft.EntityFrameworkCore.SqlServer v.7.0.10
  • Microsoft.VisualStudio.Web.CodeGeneration.Design v.7.0.9
  • Serilog.AspNetCore v.7.0.0
  • Serilog.Enrichers.Environment v.2.2.0
  • Serilog.Sinks.MSSqlServer v.6.3.0
c# asp.net-core iis impersonation serilog-aspnetcore
1个回答
0
投票

我只有两个获取当前登录用户的示例。我确信还有其他一些方法依赖于框架。

Blazor 服务器:使用 AuthenticationStateProvider 类。

    AuthenticationState authState = await _authState.GetAuthenticationStateAsync();
    ClaimsPrincipal? user = authState.User;
    if(user == null)
    {
        return false;
    }

    if(user.Identity == null)
    {
        return false;
    }

    foreach(var role in roles)
    {
        if(user.IsInRole(role))
        {
            return true;
        }
    }
    return false;

使用控制器:

var sv = HttpContext.Features.Get<IServerVariablesFeature>();
var user = (sv == null) ? "No IIS?" : sv["LOGON_USER"];

这些可能不完全是您正在寻找的,并且您可能想要添加/删除更多类型的检查,但这两者都会通过 IIS 生成当前登录的用户。

© www.soinside.com 2019 - 2024. All rights reserved.