I am building an ASP.NET Core API (1.1) in Visual Studio Code using Windows Impersonation for authentication. (The API allows researchers to create Samples
.) I am using this impersonation middleware to handle authentication, which passes on the user identity nicely when connecting to the underlying SQL Server database.
However, for some write actions, I would like to add the name of the user who created the object as a value to the database (i.e. the name of the researcher creating the sample). I can't seem to make it work. I based my solution on the responses to these questions: How to get the current logged in user Id ASP.NET Core and ASP.NET Core Identity does not inject UserManager<ApplicationUser> and this tutorial, even though they seem to be aimed at storing the user identities in separate tables in the SQL server database, which is not my intent. I only need the username of the user sending the request.
I get the following error message on the line var user = await GetCurrentUserAsync();
in my controller.
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>'
My question is twofold:
How can I fix this error?
Is there an easier/better way to get the User Identity in my situation.
My Controller
file
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
file
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
file
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
{
Database.EnsureCreated();
}
}
}
MyAPI.Model.ApplicationUser
file
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
namespace TrinityAPI.Model
{
public class ApplicationUser : IdentityUser
{
}
}