最近常開發以及維護ASP .NET Core Web API的網站,其中一個會遇到問題就是,如何在開發的情況下繞過驗證/授權(Authorization)。
這篇將介紹,如何透過設定的方式一次開啓驗證以及不驗證。
問題描述
在提到如何解決之前,先來看看指的是什麽問題。
在Controller裡面要加入驗證最簡單的方式就是把要判斷的Controller或者Action加上[Authorization]
的Attribute。
例如所有ApiBaseController
都需要經過驗證:
[Authorize]
public class ApiBaseController : ControllerBase
{
.....
}
不過有時候在開發階段卡驗證這個事情很煩,以Web Api的來説,一般來説會透過傳入bearer token
來做驗證。
每一次測試都要取得不同的Access Token
實在很煩,尤其是有時候API有問題,希望能夠排除掉是驗證有關的邏輯然後專注在API邏輯這個部分。
這個時候可以怎麽做?有沒有什麽可以在開發情況下不驗證,但是其他環境要驗證呢?
題外話:
在資安裡面認證 (Authentication) 以及 授權 (Authorization)是兩個不同的事情。
在這篇裡面指的 Authorization 是 Asp .NET 裡面的 attribute,而不是傳統意義上面的Authorization。
怎麽解決:透過加入AllowAnonymous的全域Filter
要處理這個問題有好多種解法,例如:
- 透過把BaseController裡面的
[Authorize]
拿掉 - 不過這個需要改code并且重新編譯,沒有辦法透過改設定的方式切換 - 透過build symbol不要包含
[Authorize]
- 雖然比第一個方法好一些,但是舉例來説如果用的是debug
,那麽所有的debug build都不會包含驗證 - 也是沒辦法透過設定的方式切換
還有沒有其他解決方式呢?重要是這個方式能夠透過runtime切換。
要達到這個目的一種做法是覆寫[Authorize]
,然後裡面判斷是否有權限的時候改成吃config的設定,有某個設定之結果。這個做法雖然可以解決並且也可以動態切換,但是還是有點繁瑣。
其實還有比這個更加快的做法,也就是在特定情況下,所有的Controller前面加上[AllowAnonymous]
即可。
要做到這個很簡單,只需要調整Startup.cs
:
- 把
IHostingEnvironment
注入進來 - 用環境判斷,如果是開發環境就加入
[AllowAnonymous]
把IHostingEnvironment注入進來
將會使用IHostingEnvironment.IsDevelopment()
來判斷是不是開發環境。要使用就先要注入進來,因此在Constructor做這件事情:
public IHostingEnvironment Environment { get; }
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
Environment = env;
}
有了Environment
就可以判斷出目前的執行環境是什麽。
用環境判斷,如果是開發環境就加入[AllowAnonymous]
知道了目前的執行環境是什麽之後,就可以在注冊MVC的時候,把所有的Controller加入AllowAnonymous
。
public void ConfigureServices(IServiceCollection services)
{
if (Environment.IsDevelopment())
{
services.AddMvc(opts =>
{
opts.Filters.Add(new AllowAnonymousFilter());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
else
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
......
}
邏輯還蠻清楚,當屬於Development
環境的時候,給所有的Controller加入AllowAnonymous
,換句話説不用過驗證。
如果不是開發環境,那麽就不用加,因此需要驗證的Controller都還是需要驗證。
結語
這篇解決了在開發環境讓本來要過驗證的Controller可以不用過驗證,並且直接使用了.NET Core提供的環境判斷參數,因此在上正式機器的時候不會因此忘記要開啓驗證這個事情。
如果大家有更好的做法也歡迎和我分享。