使用 Windows 身份验证的 Intranet 应用程序是否需要 ASP.NET Core Identity

mhe*_*all 5 windows-authentication claims asp.net-identity asp.net-core

在 Intranet Web 应用程序中使用 Windows 身份验证我想实现以下目标:

  • 从 AD 收集其他属性(姓名、员工编号)
  • 从数据库表中收集其他属性(工作时间、工资)
  • 基于应用程序角色(而非 AD 组)授权
  • 基于 AD 属性授权(有直接下属)
  • 用户未提供用户名/密码

在我寻找答案时,建议我需要添加ClaimsTransformation到我的应用程序中:

如何对数据库中的用户使用 Windows 身份验证

使用 .Net Core 中的 Windows Authenticated 应用程序从 SQL 填充自定义声明

.net core 2.0 中的缓存声明

虽然我不完全理解解决方案以及为什么ClaimsTransformation每个请求都会发生,所以我正在寻找以下问题的答案:

  1. 是否需要 ASP.NET Core Identity 才能ClaimsTransformation工作?
  2. 是否ClaimsTransformation仅使用 Windows 身份验证或基于表单的身份验证在每个请求上发生?
  3. 这是否必须在每个请求上发生?
  4. 缓存像 GivenName、Surname 这样的声明看起来很简单,但是角色呢?需要采取哪些步骤来确保数据库不会每次都被访问,但角色会在发生变化时得到更新。
  5. 我正在尝试做的事情有更简单的选择吗?

mhe*_*all 1

这篇文章给了我一些想法,这是一个可能的解决方案。

控制器将从具有需要Authenticated声明的策略的基本控制器继承。如果不存在,它将转到AccessDeniedPath并静默执行登录,添加Authenticated声明以及任何其他声明,如果它已经存在,则会出现“访问被拒绝”消息。

创建新身份时,ClaimsIdentity我必须删除原始身份中的大部分声明,因为我收到了HTTP 400 - 错误请求(请求标头太长)错误消息。

这种方法有什么明显的问题吗?

启动.cs

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.LoginPath = "/Home/Login";
                options.AccessDeniedPath = "/Home/AccessDenied";
            });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Authenticated",
                policy => policy.RequireClaim("Authenticated"));
            options.AddPolicy("Admin",
                policy => policy.RequireClaim("Admin"));
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器

[Authorize(Policy = "Authenticated")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [Authorize(Policy = "Admin")]
    public IActionResult About()
    {
        return View();
    }

    [AllowAnonymous]
    public async Task<IActionResult> Login(string returnUrl)
    {
        var identity = ((ClaimsIdentity)HttpContext.User.Identity);

        var claims = new List<Claim>
        {
            new Claim("Authenticated", "True"),
            new Claim(ClaimTypes.Name,
                identity.FindFirst(c => c.Type == ClaimTypes.Name).Value),
            new Claim(ClaimTypes.PrimarySid,
                identity.FindFirst(c => c.Type == ClaimTypes.PrimarySid).Value)
        };

        var claimsIdentity = new ClaimsIdentity(
            claims,
            identity.AuthenticationType,
            identity.NameClaimType,
            identity.RoleClaimType);

        await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(claimsIdentity),
            new AuthenticationProperties());

        return Redirect(returnUrl);
    }

    [AllowAnonymous]
    public IActionResult AccessDenied(string returnUrl)
    {
        if (User.FindFirst("Authenticated") == null)
            return RedirectToAction("Login", new { returnUrl });

        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)