Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I replace HttpContext.User in ASP.NET Core after Authorization?

I have a custom user class MyPrincipal with some custom properties, with which I want to replace the authenticated ClaimsPrincipal, e.g. HttpContext.User

I have added a custom middleware:

public class MyMiddleware {
  private readonly RequestDelegate next;

  public MyMiddleware(RequestDelegate next) {
    this.next = next;
  }

  public async Task Invoke(HttpContext context) {
    if (context.User.IsAuthenticated) {
      context.User = new MyPrincipal(context.User);
    }
    await next(context);
  }
}

I have registered the middleware to run after authentication, but before MVC in Startup.cs:

public void Configure(IApplicationBuilder app) {
  app.UseAuthentication();
  app.UseMiddleware<MyMiddleware()>;
  app.UseMvcWithDefaultRoute();
}

In my _Layout.cshtml I want to use a custom property from my MyPrincipal:

...
@if (User is MyPrincipal) {
  <do stuff>
}
...

So far so good, the user is recognized as MyPrincipal.

But when I add a global Authorization policy:

public void ConfigureServices(IServiceCollection services) {
  services.AddMvc(options => {
    var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
  });
}

Suddenly, the User in _Layout is just a ClaimsPrincipal.

How can I either stop MVC from replacing my principal, or hook into the pipeline after the authorization policy has completed?

P.S. I am using the ASP.NET Core 2.0 Preview 2, in case it matters.

like image 945
Geir Sagberg Avatar asked Aug 02 '17 13:08

Geir Sagberg


People also ask

How do you set HttpContext user identity for an application manually?

You can achieve this by manually settings HttpContext. User: var identity = new ClaimsIdentity("Custom"); HttpContext. User = new ClaimsPrincipal(identity);

How can get HttpContext current in ASP.NET Core?

In ASP.NET Core, if we need to access the HttpContext in service, we can do so with the help of IHttpContextAccessor interface and its default implementation of HttpContextAccessor. It's only necessary to add this dependency if we want to access HttpContext in service.

What is HttpContext user identity name?

It just holds the username of the user that is currently logged in. After login successful authentication, the username is automatically stored by login authentication system to "HttpContext.Current.User.Identity.Name" property.

How does Authorize attribute work in ASP.NET Core?

Authorization in ASP.NET Core is controlled with AuthorizeAttribute and its various parameters. In its most basic form, applying the [Authorize] attribute to a controller, action, or Razor Page, limits access to that component to authenticated users. Now only authenticated users can access the Logout function.


1 Answers

The PolicyEvaluator is authenticating the AuthenticationScheme which replaces the Principal. To fix this remove the AuthenticationScheme parameter from the AuthorizationPolicyBuilder constructor.

var policy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();

This will apply the policy to all authentication schemes and assumes you have called HttpContext.Authentication.SignInAsync elsewhere.

like image 187
Dustin Kingen Avatar answered Oct 11 '22 15:10

Dustin Kingen