2

I have a .NET Core 3+ Web API with custom authentication. I refer to it in my startup like so:

services.AddAuthentication(options =>
{
     options.DefaultAuthenticateScheme = CustomAuthOptions.DefaultScheme;
     options.DefaultChallengeScheme = CustomAuthOptions.DefaultScheme;
}).AddCustomAuthentication(options =>
   {
       options.AuthKey = "custom";
   });
   

My custom AuthenticationHandler puts various claims into the Authentication ticket. Code snippets for brevity:

public class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
    ...
    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var identity = new ClaimsIdentity("custom");

        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "someUserId"));
        identity.AddClaim(new Claim(ClaimTypes.Name, "someUserName"));

        var identities = new List<ClaimsIdentity> { identity };
        var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme);

        return Task.FromResult(AuthenticateResult.Success(ticket));
    }
}

The problem is that I would like to access these claims from the controllers. .NET Core 3 doesn't provide the User or HttpContext anymore. I found that adding the HttpContextAccessor from startup would give access from the controllers.

services.AddHttpContextAccessor();
... 
public TestController(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) { }

From the injected httpContextAccessor I can get to the claims, but I'm finding this method a bit tedious. I have to inject it in every controller (they all need the claim information). Is there not an easier way I can make these claims available to all my controllers?

Or was it .NET Core's intent to access claims in this way?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
John Lee
  • 1,357
  • 1
  • 13
  • 26
  • FWIW, that's exactly how we are accessing the claims – Felix Aug 28 '21 at 01:52
  • 2
    Controllers have `HttpContext` on themself, why inject `IHttpContextAccessor` there anyway ? You only need `IHttpContextAccessor` inject on other service that's not inherited from `ControllerBase`. – Gordon Khanh Ng. Aug 28 '21 at 02:20
  • 1
    ASP.NET Core's `ControllerBase` **DOES** have a `.User` property - [see here](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.user?view=aspnetcore-5.0) - this should give you access to the currently logged in user as a `ClaimsPrincipal` – marc_s Aug 28 '21 at 05:23
  • As mentioned in the attached link, both HttpContext and it's user properties are only available once inside the action method. My problem was that I was trying to access this from the constructor. In that case, you do need to inject the HttpContextAccessor to expose those values. – John Lee Aug 28 '21 at 19:36

0 Answers0