Apply [Authorize] attribute implicitly to all Web API controllers
Solution 1
You have two options
-
Controller level by decorating your controller with authorize attribute.
[Authorize] [RoutePrefix("api/account")] public class AccountController : ApiController {
-
You can also set it global level to all routes, in
Register
method of WebApiConfig.cs fileconfig.Filters.Add(new AuthorizeAttribute());
Solution 2
You can set the AuthorizeAttribute
to the WebApiConfig
file like below:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new AuthorizeAttribute());
}
Now all methods from your Web Api controllers will need authorization. If you want to remove this authorization requirement for a method, you need to add the attribute [AllowAnonymous]
like in the Login action method.
Solution 3
In ASP.NET Core Web API, it's like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(o =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
o.Filters.Add(new AuthorizeFilter(policy));
});
}
Source: https://joonasw.net/view/apply-authz-by-default
Solution 4
Since ASP.NET Core 3.0 there is a new way to do this without filters by using the Endpoint Routing middleware, see: https://docs.microsoft.com/en-gb/aspnet/core/migration/22-to-30?view=aspnetcore-5.0&tabs=visual-studio#authorization
You need to add the following if it's not already there:
services.UseAuthentication(); // with authentication scheme
app.UseAuthentication();
app.UseAuthorization(); // this is enough, because DefaultPolicy is to require authentication
and to the Endpoint middleware:
endpoints.MapControllers().RequireAuthorization();
An example with JWT authentication scheme:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidateAudience = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization();
});
}
You can still allow anonymous access with [AllowAnonymous]
on a controller or action (eg. for user login).
Solution 5
I just wanted to add something to other answers that if you use
filters.Add(container.Resolve<AuthorizeAttribute>());
then you can also inject all dependencies into your attribute if there is a need
amcdnl
obsessed with the web / security / tech follow me on github or twitter: @amcdnl
Updated on August 06, 2022Comments
-
amcdnl over 1 year
My application is setup where all requests except login must be 'authorized' using the authorization attribute in Web API. E.g.
[Authorize] [HttpGet, Route("api/account/profile")] public ApplicationUser Profile() { return userModel; }
and only the login needs to not authorize since thats where you get the token ;)
[AllowAnonymous] [HttpPost, Route("api/account/login")] public async Task<IHttpActionResult> Login(LoginViewModel model) { .... }
instead of having to add the
[Authorize]
attribute to ALL my routes, is there a way to set it globally? -
ilans almost 9 yearsI'd also recommend to put this inside a
#if !DEBUG #endif
block, so this could ease debugging without the need for authorization. -
Piero Alberto over 4 yearsI did this, but now I get ALWAYS 401, sure I'm missing something... what else I need to add?
-
Balagurunathan Marimuthu about 3 yearsSide-note: recent version of .net core api, need to add
Policy
forAuthorizeAttribute
as Matt Frear answered below.