Search code examples
c#asp.net.netasp.net-identityasp.net-core-2.0

AuthorizeAttribute for Web API (ASP.NET Core 2)


I want to use AuthorizeAttribute for my Web API methods. But when user is not authorized method returns Login-View instead simple 401-status-code.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{           
    // Another code.
    services.AddDefaultIdentity<User>(opt => {})
    .AddEntityFrameworkStores<MyDbContext>();
    // Another code.
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Another code.
    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "api/{controller}/{action=Index}/{id?}");
    });

    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";

        if (env.IsDevelopment())
        {
            spa.UseReactDevelopmentServer(npmScript: "start");
        }
    });
    // Another code.
}

SimpleController.cs:

[Route("api/[controller]")]
public class SimpleController : Controller
{
    [Authorize]
    [HttpGet("{id}")]
    public int Index(int Id)
    {
        return Id;
    }
}

In ASP.NET MVC 5 we have both AuthorizeAttribute:

  1. System.Web.Http.AuthorizeAttribute - which is used for the web API.
  2. System.Web.Mvc.AuthorizeAttribute - which is used for controllers with views.

But ASP.NET Core 2.0 has only one kind of attribute - for controllers with views. What do I need to do to get status-codes (401, 403) instead views?


Solution

  • ASP.NET Core Identity uses cookie authentication and therefore you can override CookieAuthenticationOptions.Events to make it work as you need. Identity provides ConfigureApplicationCookie configuration method for this.

    services.ConfigureApplicationCookie(options =>
    {
        //this event is called when user is unauthorized and is redirected to login page
        options.Events.OnRedirectToLogin = context =>
        {
            context.Response.StatusCode = 401;
    
            return Task.CompletedTask;
        };
    });