ASP.NET 使用模拟的核心无法访问用户身份
ASP.NET Core using Impersonation cannot access User Identity
我正在 Visual Studio 代码中构建一个 ASP.NET 核心 API (1.1),使用 Windows 模拟进行身份验证。 (API 允许研究人员创建 Samples
。)我正在使用这个 impersonation middleware 来处理身份验证,当连接到底层 SQL 服务器数据库时,它可以很好地传递用户身份.
但是,对于某些写入操作,我想将创建对象的用户的名称作为值添加到数据库中(即创建样本的研究人员的名称)。我似乎无法让它发挥作用。我的解决方案基于对这些问题的回答: and and this tutorial,尽管它们似乎旨在将用户身份存储在 SQL 服务器数据库的单独表中,但这不是我的意图。我只需要发送请求的用户的用户名。
我在控制器的 var user = await GetCurrentUserAsync();
行收到以下错误消息。
The 'await' operator can only be used within an async method.
Consider marking this method with the 'async' modifier
and changing its return type to 'Task<IActionResult>'
我的问题是双重的:
如何解决这个错误?
在我的情况下,是否有 easier/better 获取用户身份的方法。
我的Controller
文件
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using MyAPI.Model;
using MyAPI.Services;
namespace MyAPI.Controllers
{
[Route("api/[controller]")]
public class SamplesController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
[HttpPost]
public IActionResult Post([FromBody] Sample sample)
{
var user = await GetCurrentUserAsync();
var userId = user?.Id;
// I abstracted the underlying logic of creating a sample in the database
//because it is quite complex and doesn't seem relevant to this problem
CreateSample(sample, userId);
}
}
}
Startup.cs
文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using MyAPI.Model;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Impersonate.AspNetCore.Windows;
namespace MyAPI
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseWindowsImpersonation(options => { options.Enabled = true; });
app.UseMvc();
}
}
}
MyAPI.Model.ApplicationDbContext
文件
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
{
Database.EnsureCreated();
}
}
}
MyAPI.Model.ApplicationUser
文件
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationUser : IdentityUser
{
}
}
启用 Windows 身份验证并在控制器操作的代码中,您可以通过转到 HttpContext 属性 上的用户对象来查找有关当前用户的信息。例如,以下操作应为当前用户显示 domain\username。
public IActionResult Index()
{
return Content(HttpContext.User.Identity.Name);
}
当使用 Windows 身份验证时,您认为不想使用 ASP.NET 身份验证是正确的。您可以删除 ApplicationDbContext class 以及 Startup class.
中的 AddIdentity 调用
我正在 Visual Studio 代码中构建一个 ASP.NET 核心 API (1.1),使用 Windows 模拟进行身份验证。 (API 允许研究人员创建 Samples
。)我正在使用这个 impersonation middleware 来处理身份验证,当连接到底层 SQL 服务器数据库时,它可以很好地传递用户身份.
但是,对于某些写入操作,我想将创建对象的用户的名称作为值添加到数据库中(即创建样本的研究人员的名称)。我似乎无法让它发挥作用。我的解决方案基于对这些问题的回答:
我在控制器的 var user = await GetCurrentUserAsync();
行收到以下错误消息。
The 'await' operator can only be used within an async method.
Consider marking this method with the 'async' modifier
and changing its return type to 'Task<IActionResult>'
我的问题是双重的:
如何解决这个错误?
在我的情况下,是否有 easier/better 获取用户身份的方法。
我的Controller
文件
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using MyAPI.Model;
using MyAPI.Services;
namespace MyAPI.Controllers
{
[Route("api/[controller]")]
public class SamplesController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
[HttpPost]
public IActionResult Post([FromBody] Sample sample)
{
var user = await GetCurrentUserAsync();
var userId = user?.Id;
// I abstracted the underlying logic of creating a sample in the database
//because it is quite complex and doesn't seem relevant to this problem
CreateSample(sample, userId);
}
}
}
Startup.cs
文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using MyAPI.Model;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Impersonate.AspNetCore.Windows;
namespace MyAPI
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseWindowsImpersonation(options => { options.Enabled = true; });
app.UseMvc();
}
}
}
MyAPI.Model.ApplicationDbContext
文件
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
{
Database.EnsureCreated();
}
}
}
MyAPI.Model.ApplicationUser
文件
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationUser : IdentityUser
{
}
}
启用 Windows 身份验证并在控制器操作的代码中,您可以通过转到 HttpContext 属性 上的用户对象来查找有关当前用户的信息。例如,以下操作应为当前用户显示 domain\username。
public IActionResult Index()
{
return Content(HttpContext.User.Identity.Name);
}
当使用 Windows 身份验证时,您认为不想使用 ASP.NET 身份验证是正确的。您可以删除 ApplicationDbContext class 以及 Startup class.
中的 AddIdentity 调用