asp.net-core - Asp.net core,调试时绕过授权
问题描述
我有一个测试网站,它[AuthorizeAttribute]
在整个控制器级别使用 aspnetCore,以确保只有经过身份验证的用户才能访问该网站。
当我们调试和测试新功能时,我们必须经常注释掉每个控制器中的属性,我知道这很容易忘记并且可能有一天会被合并。
我们在检查之前是否附加了调试器方面取得了很大的成功......我想知道我应该指定哪个 AuthenticationScheme 以允许匿名,只有在调试时。
我扩展了基础 AuthorizeAttribute,所以我有一个简单的地方可以在一些代码中填充。
public class MyAppAuthorizeAttribute : AuthorizeAttribute
{
public MyAppAuthorizeAttribute()
: base(Policies.MyAppAuthorize)
{
if (System.Diagnostics.Debugger.IsAttached)
{
Console.WriteLine("Skipping auth for debug"); //we hit this line but...
this.AuthenticationSchemes = AllowAnonymousAttribute //this setting does not work
}
else
{
this.AuthenticationSchemes = "IntegratedWindowsAuthentication";
}
}
}
解决方案
在某些情况下,您可能需要对用户进行身份验证,但代码中并未实际引用您的要求(例如:代码不访问有关当前身份的任何信息,尤其是与用户的业务模型相关的信息)。因此,我假设您已经意识到这一点,因为以下内容只是简单地删除了在开发环境中运行代码时检查经过身份验证的用户的要求。还有另一种自动登录虚拟用户的方法,在某些情况下可能会更好。
这是第一个解决方案,它只配置一个不包含的默认策略DenyAnonymousAuthorizationRequirement
(这是默认策略中包含的唯一要求)。这意味着如果您在某处使用了多个策略(带有AuthorizeAttribute
),则只有默认值将被忽略(在调试时)。第二种解决方案(稍后显示)可能更适合这种情况。
//inject IHostingEnvironment in the Startup constructor
public Startup(IConfiguration configuration, IHostingEnvironment env){
HostingEnvironment = env;
}
public IHostingEnvironment HostingEnvironment { get; }
//in the ConfigureServices method in Startup.cs
services.AddAuthorization(o => {
if (HostingEnvironment.IsDevelopment()){
o.DefaultPolicy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
//there should be at least 1 requirement
//here we add a simple always-passed assertion
.RequireAssertion(e => true).Build();
}
//...
});
我们需要使用IHostingEnvironment
(在 .net core 2.2 中,自 3.0 以来我们有 2 个替代方案IWebHostEnvironment
和IHostEnvironment
),因此我们将其注入Startup
构造函数并将其存储在只读属性中(如上所示)。还有另一种方法是尝试ASPNETCORE_ENVIRONMENT
像这样直接获取变量:
var isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
这是您使用自定义全局IAsyncAuthorizationFilter
自动登录虚拟用户的第二个解决方案(因此它始终对所有请求进行身份验证)。
public class AllowAnonymousFilterAttribute : Attribute, IAsyncAuthorizationFilter
{
readonly IHostingEnvironment _hostingEnvironment;
public AllowAnonymousFilterAttribute(IHostingEnvironment env){
_hostingEnvironment = env;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (_hostingEnvironment.IsDevelopment() && !context.HttpContext.User.Identity.IsAuthenticated)
{
//prepare a dummy user to auto sign-in
HttpContext.User = new ClaimsPrincipal(new[] {
new ClaimsIdentity(new []{ new Claim(ClaimTypes.NameIdentifier,"admin")},
CookieAuthenticationDefaults.AuthenticationScheme)
});
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
HttpContext.User);
}
}
}
全局注册过滤器,这里我写代码.net core 2.2
:
services.AddMvc(o => {
//register the filter only for development (should be debugging)
if (HostingEnvironment.IsDevelopment()){
o.Filters.Add<AllowAnonymousFilterAttribute>();
}
//...
});
我敢肯定还有其他一些解决方案,但是我在这里介绍的内容相当简单,并且足以满足您的目的。
P/S:我上面介绍的第一个解决方案适用于.net core 2.2(实际上我目前无法访问更新版本的.net core,很遗憾)。对于较新的版本,Authorization
中间件是独立的,因此您可能只是不像另一个答案所建议的那样.UseAuthorization()
在方法中调用中间件Configure
推荐阅读
- reactjs - 登录后在哪里存储用户信息:React JS
- python - Scrapy不返回任何结果
- docker - Docker Running 在容器内运行,但无法通过浏览器访问
- php - WordPress 5.6 错误编辑主题 header.php “无法与站点通信以检查致命错误,因此恢复了 PHP 更改。”
- python - 如何从两个数组中找到匹配的元素和索引?
- windows-10 - Coral Edge TPU USB 加速器驱动安装失败
- python - 为什么使用 pyinstaller 创建的使用语音识别的 .exe 文件没有运行?
- python - views.py 文件的 Django 最佳实践?
- angular - 如何将 js 文件作为 Angular 库的一部分导入
- java - 为什么即使我不调用 get() 或 join(),这个 CompletableFuture 也能工作?