在我的.net6 Web API项目中,需求是执行Windows身份验证。 创建项目时,我已将“身份验证”下拉列表选择为“Windows”。出于测试目的,我只构建了一个端点,它返回 4 个简单参数作为响应。
我的program.cs文件
using IdentityTestWindows;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
我的控制器
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.DirectoryServices.Protocols;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace IdentityTestWindows.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class LoginController : ControllerBase
{
private readonly IConfiguration _config;
public LoginController(IConfiguration config)
{
this._config = config;
}
// GET: api/<LoginController>
[HttpGet("authenticateLogin")]
public async Task<ActionResult> Authenticate()
{
try
{
var result = new
{
ApplicationCodeExecutedUsing = WindowsIdentity.GetCurrent().Name.ToString(),
IsUserAuthenticated = User.Identity.IsAuthenticated.ToString(),
AuthenticationType = User.Identity.AuthenticationType.ToString(),
UserName = User.Identity.Name,
};
return Ok(result);
}
catch (Exception)
{
throw;
}
}
}
}
此代码在本地 IIS 服务器应用程序中按预期工作。但我的要求是这应该在公共网络中正常工作。假设我的所有用户计算机都遵循 Organization_Domain\{Employee_ID} 模式作为其 Windows 身份。符合上述匹配条件的用户不应请求授权。
我探索了 Windows 身份验证,在 .NET Framework 中,我发现 web.config 中的标签也对于 Intranet 场景“模拟”更合适。但是.NET6 web.config不接受web.config中的标签授权。
所以,我请求有关此问题的帮助。
您的 web.config 模拟设置不适用于 .net 最新版本,因为它被设计为跨平台。您可以使用协商身份验证处理程序来实现您的要求。为此,您可以按照以下步骤操作:
1)设置IIS以启用Windows身份验证并禁用匿名
2) 在 Internet Explorer 设置中启用“集成 Windows 身份验证”。
选择“本地 Intranet”,然后选择“自定义级别”或“高级”按钮。
向下滚动至“用户身份验证”>“登录”。
选中“仅在 Intranet 区域中启用登录”旁边的复选框。
3)设置自定义授权策略以检查用户是否匹配组织的域模式:
public class EmployeeIdRequirement : IAuthorizationRequirement
{
// Custom requirement
}
public class EmployeeIdAuthorizationHandler : AuthorizationHandler<EmployeeIdRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, EmployeeIdRequirement requirement)
{
var windowsIdentity = context.User.Identity as WindowsIdentity;
if (windowsIdentity != null && windowsIdentity.Name.StartsWith("Organization_Domain\\"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
然后注册此处理程序并根据需要将策略应用到您的控制器或操作:
builder.Services.AddSingleton<IAuthorizationHandler, EmployeeIdAuthorizationHandler>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeIdPolicy", policy =>
policy.Requirements.Add(new EmployeeIdRequirement()));
});
[Authorize(Policy = "EmployeeIdPolicy")]
public class YourController : ControllerBase
{
// Controller actions
}