gpt4 book ai didi

asp.net-core - .NET Core 3.1 WebApi 项目 + NTLM 认证

转载 作者:行者123 更新时间:2023-12-04 04:17:33 25 4
gpt4 key购买 nike

我正在尝试迁移使用此类东西的旧 OWIN 自托管 WebApi

    var listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;

到新的 .NET Core 3.1 项目。我读过 Auth

这是我的项目文件的样子

  <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Text.Json" Version="4.7.0" />
</ItemGroup>
</Project>

这就是我的 launchsettings.json 的样子

{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:9600",
"sslPort": 0
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/audit",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"use64Bit": true
},
"Audit.Core": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/audit",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:9600"
},
"Azure Dev Spaces": {
"commandName": "AzureDevSpaces",
"launchBrowser": true
}
}
}

这就是我的 Startup.cs 的样子

    using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.AspNetCore.Server.IISIntegration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NLog;

namespace xxxx
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
services.AddControllers().AddNewtonsoftJson();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseRouting();

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

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

这是 Program.cs

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.NTLM;
options.EnableResponseCaching = false;
options.Authentication.AllowAnonymous = false;
});
})
.ConfigureWebHost(config =>
{
config.UseUrls("http://*:9600");
});
}

我有一个自定义过滤器,我需要从中获取当前用户的身份并验证它是否具有与其关联的某个 ActiveDirectory 组。基本用法是这样的

    [ApiController]
[Route("api/some")]
[ControllerExceptionFilter]
public class SomeController : ControllerBase
{
[HttpPost("add")]
[ActiveDirectoryAuthorize("SomeGroup")]
public IActionResult Add([FromBody]SomeEvent s)
{
var user = this.HttpContext.User.Identity;
return Ok("cool");
}
}

过滤器看起来像这样

    //https://stackoverflow.com/questions/31464359/how-do-you-create-a-custom-authorizeattribute-in-asp-net-core
public class ActiveDirectoryAuthorizeAttribute : TypeFilterAttribute
{
public ActiveDirectoryAuthorizeAttribute(string groupMembership) : base(typeof(ActiveDirectoryAuthorizeFilter))
{
Arguments = new object[] { groupMembership };
}
}

public class ActiveDirectoryAuthorizeFilter : IAuthorizationFilter
{
private string _groupMembership;
public ActiveDirectoryAuthorizeFilter(string groupMembership)
{
_groupMembership = groupMembership;
}

public void OnAuthorization(AuthorizationFilterContext context)
{
try
{
Authenticate(context);
}
catch (InvalidWindowsUserException ex)
{
HandleUnauthorizedRequest(context);
}

catch (Exception ex)
{
HandleInternalServerError(context);
}
}

protected void HandleUnauthorizedRequest(AuthorizationFilterContext context)
{
context.HttpContext.Response.Headers.Add("WWW-Authenticate", "NTLM");
context.Result = new ContentResult
{
Content = "Unauthorized",
StatusCode = (int)HttpStatusCode.Unauthorized
};
}

private void HandleInternalServerError(AuthorizationFilterContext context)
{
context.HttpContext.Response.Headers.Add("WWW-Authenticate", "NTLM");
context.Result = new ContentResult
{
Content = "Internal Server Error",
StatusCode = (int)HttpStatusCode.InternalServerError
};
}

private void Authenticate(AuthorizationFilterContext context)
{
var identity = context?.HttpContext?.User?.Identity;

if (identity == null)
{
throw new InvalidWindowsUserException("Access denied");
}

EnsureAdmin(identity);
}

private void EnsureAdmin(IIdentity identity)
{
......
}
}

所有这些都准备就绪后,我可以启动 POSTMAN 并使用 BAD 密码发出 NTLM 请求,我得到 401。这是预期的

enter image description here

然后我编辑 POSTMAN 请求以输入正确的密码,我得到了这个,在那里我得到了 200 并从上面显示的 Controller 得到了“酷”的响应

enter image description here

到目前为止,一切都按预期工作。但是,如果我随后更改当前工作的 POSTMAN (200 ok) 请求以再次使用 BAD NTLM 密码。我原以为会看到 401,但当前用户只是在我的自定义过滤器中显示为仍被授权

enter image description here我实际上得到了 200 OK

enter image description here

此行为不同于旧的基于 OWIN 的 WebApi。哪个确实识别了以下序列

  1. NTLM 密码错误,401 未经授权
  2. NTLM 好的密码,200 OK
  3. NTLM 密码错误,401 未经授权

我还需要在某处设置其他东西吗?有人对此有任何线索吗?

最佳答案

我遇到过同样的情况,在我看来这是一个 Postman 问题,就像它是否“缓存”了正确的密码,并且即使你用错误的密码更改它也会继续发送它。

如果您退出并重新进入 Postman,并使用错误的密码重复上次请求,您将得到“正确”的 401 Unauthorized,即:

 1. NTLM bad password              -> 401 Unauthorized - correct
2. NTLM good password -> 200 OK - correct
3. NTLM bad password -> 200 OK - WRONG, as if Postman cached the good password
4. Exit Postman - Re-enter Postman
5. NTLM bad password (same as 3.) -> 401 Unauthorized - correct

也许它与 NTLM 认证方案有关,这意味着一个“挑战”,即,在幕后有一个“协商”,有几个 HTTP 调用由 Postman 透明地处理,但是如果你改变密码。

编辑:值得一提的是,Postman 中的 NTLM 身份验证功能目前处于测试阶段

关于asp.net-core - .NET Core 3.1 WebApi 项目 + NTLM 认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60324311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com