使用Impersonation的ASP.NET Core无法访问用户身份

时间:2017-07-05 15:59:36

标签: c# asp.net-core impersonation asp.net-core-1.1

我正在使用Windows Impersonation在Visual Studio代码中构建ASP.NET Core API(1.1)进行身份验证。 (API允许研究人员创建Samples。)我使用此impersonation middleware来处理身份验证,在连接到基础SQL Server数据库时很好地传递用户身份。

但是,对于某些写入操作,我想将创建对象的用户的名称添加为数据库的值(即创建样本的研究人员的名称)。我似乎无法使其发挥作用。我的解决方案基于对这些问题的回答:How to get the current logged in user Id ASP.NET CoreASP.NET Core Identity does not inject UserManager<ApplicationUser>以及此tutorial,即使它们似乎旨在将用户身份存储在SQL Server数据库的单独表中,这不是我的意图。我只需要发送请求的用户的用户名。

我在控制器的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>'

我的问题有两个:

  1. 如何修复此错误?

  2. 在我的情况下,是否有更简单/更好的方式来获取用户身份。

  3. 我的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
      {
      }
    }
    

1 个答案:

答案 0 :(得分:2)

启用Windows身份验证并在控制器操作的代码内部,您可以通过转到HttpContext属性上的User对象来查找有关当前用户的信息。例如,以下操作应显示当前用户的domain \ username。

print(str(i) + ":", each, ...)

使用Windows身份验证时,您认为自己并不想使用ASP.NET身份是正确的。您可以在Startup类中删除ApplicationDbContext类以及AddIdentity调用。