はじめに
ASP.Net を使用してControllerを使うとき、認証キーがなければ通過できないように[Authorize]を使用しますが、たくさんのControllerを使用していると、書き忘れてしまうことがある・・・かもしれません。
そんなときには、書いてなくても有効にできる方法がありましたので記載します。
環境
ASP.Net 6.0
Program.csの書き方が6.0に合わせていますが、それ以前の環境でも少し違うだけなので大丈夫かなと思います。
初期値
ASP.NET Core Web API をVisual Studioで作成すると以下のようなProgram.csとWeatherForecastController.csができると思います。6.0はかなりシンプルですね。
Program.cs
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();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
WeatherForecastController.cs
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
Authorizedのやり方
よくある方法は各コントローラーに[Authorize]をつけて、だれでも使用できるAPIに[AllowAnonymous]をつけることです。
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
[AllowAnonymous]
[HttpPost("login")]
public async Task<ActionResult> Login(LoginModel loginModel)
これでも問題はないのですが、Controllerが作成された場合[Authorize]はついていないので、毎回書き足す必要があります。もし書き忘れていたらセキュリティ的な問題となります。
ということで、対策方法ですが、とても簡単で、Program.csに設定を書いてしまうという方法です。
Program.csにフォールバック認可ポリシーを追記する
builder.Services.AddControllers(options =>
{
options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
});
このようにすることで、インスタンスにDenyAnonymousAuthorizationRequirementが追加されて、すべてのコントローラーが[Authorize]となります。
[Authorize]がデフォルトとなり、[AllowAnonymous]をつけたものだけが誰でも許可という属性になります。
ちなみに、JwtToken認証を使用する場合は以下のようにすればOKです。
options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build()));
これを知ってから、作業効率が上がった気がしています。