是否可以在不改变逻辑的情况下在asp.net核心应用程序中"禁用"身份验证?
我有一个.net网站,它使用外部身份服务器应用程序进行身份验证.无论如何,我希望能够在我开发它时模拟身份验证(ASPNETCORE_ENVIRONMENT =开发),对所有忽略授权属性的操作进行访问.
是否可以仅仅模拟服务集合中的某些服务?
Sim*_*per 45
在更新到 net core 3.1 时,mvcAllowAnonymousFilter
不再为我们工作。我们发现有条件地添加自定义IAuthorizationHander
是有条件地绕过身份验证的最简单方法。
例如。
/// <summary>
/// This authorisation handler will bypass all requirements
/// </summary>
public class AllowAnonymous : IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
foreach (IAuthorizationRequirement requirement in context.PendingRequirements.ToList())
context.Succeed(requirement); //Simply pass all requirements
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Startup.ConfigureServices
.
private readonly IWebHostEnvironment _env;
public Startup(IWebHostEnvironment env)
{
_env = env;
}
public void ConfigureServices(IServiceCollection services)
{
{...}
//Allows auth to be bypassed
if (_env.IsDevelopment())
services.AddSingleton<IAuthorizationHandler, AllowAnonymous>();
}
Run Code Online (Sandbox Code Playgroud)
NoteAddAuthentication
和AddAuthorization
服务仍然按照 prod 代码进行注册和配置(这很好)。
为了让我们的单元测试绕过身份验证,我们添加了一个新的匿名测试库,其中包含一个启动类,该类在没有任何条件的情况下添加了这一行。好看又简单!
rox*_*ton 21
在 ASP.NET Core 3.x 及更高版本中,您可以通过使用扩展方法应用AllowAnonymousAttribute
到您的端点来绕过开发环境中的授权。Startup.Configure()
WithMetadata
示例 1.适用AllowAnonymousAttribute
于控制器:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseEndpoints(endpoints =>
{
if (env.IsDevelopment())
endpoints.MapControllers().WithMetadata(new AllowAnonymousAttribute());
else
endpoints.MapControllers();
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,这将适用AllowAnonymousAttribute
于所有控制器。
示例 2.应用于AllowAnonymousAttribute
构建的端点MapGet()
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseEndpoints(endpoints =>
{
var hiEndpoint = endpoints
.MapGet("/hi", async context => await context.Response.WriteAsync("Hello!"))
.WithMetadata(new AuthorizeAttribute());
if (env.IsDevelopment())
hiEndpoint.WithMetadata(new AllowAnonymousAttribute());
});
}
Run Code Online (Sandbox Code Playgroud)
细节
endpoints
,它是 的一个实例IEndpointRouteBuilder
,有多个Map
扩展方法,如MapControllers()
和MapGet(...)
返回IEndpointConventionBuilder
。
WithMetadata
是IEndpointConventionBuilder
这些endpoints.Map
方法的扩展 ,可以调用这些方法的结果。
AllowAnonymousAttribute
来自文档的描述:
指定应用此属性的类或方法不需要授权。
ozz*_*zzy 16
您可能要考虑的另一个解决方案是使用 IPolicyEvaluator。这意味着您可以保留所有现有的安全元素。
public class DisableAuthenticationPolicyEvaluator : IPolicyEvaluator
{
public async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
{
// Always pass authentication.
var authenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(), new AuthenticationProperties(), JwtBearerDefaults.AuthenticationScheme);
return await Task.FromResult(AuthenticateResult.Success(authenticationTicket));
}
public async Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource)
{
// Always pass authorization
return await Task.FromResult(PolicyAuthorizationResult.Success());
}
}
Run Code Online (Sandbox Code Playgroud)
在 Startup.cs 中,确保它出现在 ConfigureServices 方法的顶部。例如。
public void ConfigureServices(IServiceCollection services)
{
if (env.IsDevelopment())
{
// Disable authentication and authorization.
services.TryAddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
}
...
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Core 3.1 并且希望使用 WebApplicationFactory,而不是 Startup.cs(并感谢下面的评论),您可以执行以下操作:
public class MyWebApplicationFactory : WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices(services =>
{
// Disable Authentication.
services.RemoveAll<IPolicyEvaluator>();
services.AddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
});
}
}
Run Code Online (Sandbox Code Playgroud)
小智 15
此代码必须有效:
if (env.IsDevelopment()) {
services.AddMvc(opts =>
{
opts.Filters.Add(new AllowAnonymousFilter());
});
} else {
services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)
在没有更多详细信息的情况下给出详细答案是很棘手的,但我之前通过有条件地注册来实现这一点:
它看起来像:
public class Startup
{
public Startup(IHostingEnvironment env)
{
Environment = env;
}
public IHostingEnvironment Environment { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(x =>
{
if (!Environment.IsDevelopment())
{
var authenticatedUserPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
x.Filters.Add(new AuthorizeFilter(authenticatedUserPolicy));
}
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseStaticFiles();
if (!Environment.IsDevelopment())
{
// Register external authentication middleware
}
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Run Code Online (Sandbox Code Playgroud)
就我而言,授权过滤器是全局应用的,因此MVC应用程序的每个操作都需要经过身份验证的用户.
如果您有不同的要求 - [Authorize]
某些操作的细粒度属性 - 那么您可以通过更改相关授权策略的构建方式来实现相同的结果.它们基本上根本不包含任何要求.
AuthorizationPolicy yourCustomPolicy = null;
if (Environment.IsDevelopment())
{
yourCustomPolicy = new AuthorizationPolicyBuilder().Build();
}
else
{
yourCustomPolicy = new AuthorizationPolicyBuilder()
// chaining appropriate methods to suit your needs
.Build();
}
Run Code Online (Sandbox Code Playgroud)
在 ASP.NET Core 6 中,我们设法禁用授权,而无需更改生产代码中的任何其他部分,只需 Program.cs 中的以下逻辑:
if (!builder.Environment.IsDevelopment())
{
app.MapControllers();
}
else
{
app.MapControllers().AllowAnonymous();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5683 次 |
最近记录: |