I am rebuilding an intranet suite using .NET 6.0 and React. In this process I need to have the user's name in order to look up necessary data on that user. It's in an active directory domain with SSO authentication, so the web browser should be passing that data to the API endpoint. In .NET Framework 4.5 I could simple call HttpContext.current.user.identity.name
to get the information I need. However in 6.0 it seems that there is no access to the current context.
I have added builder.Services.AddHttpContextAccessor();
in my program.cs and tried using
public class SitemapController : Controller
{
ClaimsPrincipal user;
public SitemapController(IHttpContextAccessor context)
{
//User.Identity comes up null here
user = context.HttpContext.User;
}
// GET: api/<SitemapController>
[HttpGet]
public string Get() //IEnumerable<Intranet2.MCA.SitemapEntry>
{
Console.WriteLine("Sitemap Test");
//this.User is also null (saw this recommendation somewhere)
var userName = this.User.Identity.Name;
var siteMap = Data.Sitemap();
return siteMap;
}
}
to retrieve the user name but it only returns null. My authentication type in Web.Config is set to Windows and I am using IISExpress while developing this.
After a day of looking how to do this I have come to a dead end. I have seen some pages recommending adding IHttpContextAccessor code to the Startup.cs file in the Startup class but my project doesn't contain those files.
I have tried this on 2 separate machine, one through a VPN and the other directly on the network with identical results.
What is a way I can access the information I need. There doesn't seem to be a simple method to access it.
EDIT Adding all updated code after following comments.
//SitemapController.cs
namespace webapi.Controllers
{
[ApiController]
[Route("[controller]")]
public class SitemapController : Controller
{
// GET: api/<SitemapController>
[HttpGet]
public string Get()
{
Console.WriteLine("Sitemap Test");
var user = this.User.Identity.Name;
var siteMap = Data.Sitemap();
return siteMap;
}
}
}
//Program.cs
using Microsoft.AspNetCore.Authentication.Negotiate;
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();
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();
What is a way I can access the information I need. There doesn't seem to be a simple method to access it.
Based on your shared code snippet, if you would like to access logged in windows user information you should configure AuthorizationOptions which is currently not seen within your code and within AuthorizationOptions you ought to pass DefaultPolicy in order to extract Windows user Name.
In addition to this, you also need to use both UseAuthentication and UseAuthorization service as well.
Let's have a look in practice:
LaunchSetting.json:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:44272",
"sslPort": 44364
}
}
Note: Within iisSettings you should have windowsAuthentication to true.
Program.cs file:
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
app.UseAuthentication();
app.UseAuthorization();
Note: You are missing this AddAuthorization service configuration which ensures all incoming requests will be authorized according to the default policy.
Reference Required:
using Microsoft.AspNetCore.Authentication.Negotiate;
Note: Nuget package can be found here.
Controller:
[Route("api/[controller]")]
[ApiController]
public class SiteMapController : ControllerBase
{
[HttpGet("GetUserWindowsUserName")]
public IActionResult GetUserWindowsUserName()
{
string gettingWindowsUser = HttpContext.User.Identity?.Name!;
var responseMessage = string.Format("Current Windows User Name: {0}", gettingWindowsUser);
return Ok(responseMessage);
}
}
Output:
Note: You can have look on the details example here.