Asp .net Core 3.1 windows auth 用户模拟调用webapi

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

我有一个使用 Windows 身份验证的 .net core 3.1 Web 应用程序。 Web 应用程序需要以用户身份 向 .net Core 3.1 API 发出请求,并且该 API 还需要以用户身份 调用其他内部网服务。该应用程序和 API 托管在同一台服务器上,并且都使用 Windows 身份验证。

模拟当前 Windows 授权用户发出 API 请求的正确方法是什么?(应用程序可以在不模拟的情况下成功调用 API,但请求将作为应用程序池用户运行。)两个测试

HomeController
中的方法是通过搜索 MS 文档和 SO 示例的日子拼凑而成的,但每个方法都会为版本
FileLoadException
生成一个
System.Net.Http
,该版本没有被 .csproj 文件引用——并且它仅在使用模拟时发生。

// impersonation in the method
public async Task<IActionResult> AskForSomethingWithImpersonationAsync()
{
    var apiBase = new Uri(configuration["Api"]);
    var response = string.Empty;
    var user = (WindowsIdentity)HttpContext.User.Identity;

    await WindowsIdentity.RunImpersonated(user.AccessToken, async () =>
    {
        var credentialsCache = new CredentialCache { { apiBase, "NTLM", CredentialCache.DefaultNetworkCredentials } };
        var handler = new HttpClientHandler() { Credentials = credentialsCache };
        var httpClient = new HttpClient(handler) { BaseAddress = apiBase, Timeout = new TimeSpan(0, 0, 10) };
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        response = httpClient.GetStringAsync("/api/v2/log").Result;
    });

    return Content(response);
}

// impersonation middleware
[ServiceFilter(typeof(ImpersonationFilter))]
public async Task<IActionResult> AskForSomethingFilteredAsync()
{
    var apiBase = new Uri(configuration["Api"]);
    var response = string.Empty;
    var user = (WindowsIdentity)HttpContext.User.Identity;

    var credentialsCache = new CredentialCache { { apiBase, "NTLM", CredentialCache.DefaultNetworkCredentials } };
    var handler = new HttpClientHandler() { Credentials = credentialsCache };
    var httpClient = new HttpClient(handler) { BaseAddress = apiBase, Timeout = new TimeSpan(0, 0, 10) };
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    response = await httpClient.GetStringAsync("/api/v2/log");

    return Content(response);
}

这里是模拟过滤器中间件:

using Microsoft.AspNetCore.Mvc.Filters;
using System.Security.Principal;
using System.Threading.Tasks;

namespace HBACaller.ActionFilter
{
    public class ImpersonationFilter : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(
            ActionExecutingContext context,
            ActionExecutionDelegate next)
        {
            var user = (WindowsIdentity)context.HttpContext.User.Identity;

            await WindowsIdentity.RunImpersonated(user.AccessToken, async () =>
            {
                await next();
            });
        }
    }
}

这是我在网络浏览器的网络响应选项卡中看到的错误:

System.IO.FileLoadException: 
File name: 'System.Net.Http, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

据我所知,该版本未在任何地方引用。 .csproj 有这个:

<ItemGroup>
  <PackageReference Include="System.Net.Http" Version="4.3.4" />
  <PackageReference Include="System.Security.Principal" Version="4.3.0" />
</ItemGroup>

当此代码发布到测试 IIS 服务器而不是通过 Visual Studio 在本地运行时,异常末尾会附加一条消息:

Either a required impersonation level was not provided, or the provided impersonation level is invalid.

如果它有助于查看完整的(失败的)项目,这是回购协议:https://github.com/cestarte/core_impersonate_winauth_user

api asp.net-core authentication impersonation
1个回答
-1
投票

对于任何试图进行“支持”风格模拟的人,即您以另一个用户身份登录,.net identity 通常在 signinmanager 下有一个名为 PasswordSignInAsync 的功能,但它还有一个很少使用的 SignInAsync,它不需要密码。 Windows Identity / Active Directory 身份验证已死,因为我们已经拥有互联网 25 年了,还因为发生的一切只是你和管理服务器的不可避免的令牌 IT 人员之间的一场愚蠢的战斗,就像任何在 2023 年拥有 AD 的企业一样活在过去,说 IT 人只是在那里为自己的工作安全制造假问题。因此,依赖 AD 身份验证的应用程序在现实世界中永远不会持久。 IT 人员只是更改用户的密码,使您的应用程序失败。

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