【问题标题】:ASP.NET Core 3 mock authorization during integration testing集成测试期间的 ASP.NET Core 3 模拟授权
【发布时间】:2020-01-03 11:06:55
【问题描述】:

我正在使用 ASP.NET core 构建 API,我正在尝试从 .NET core 2.2 升级到 .NET core 3.1。

我正在使用 [Authorize] 属性来保护 API 端点,我想在集成测试期间绕过它。

我已经设法创建了一个自定义 AuthenticationHandler 来验证假用户,以及一个授权处理程序来授权任何人(包括匿名用户)。

我的问题是在身份验证处理程序中注入的用户没有传播到授权处理程序并且过滤器DenyAnonymousAuthorizationRequirement 失败 因为上下文中的用户为空。

有没有人处理过类似的事情?

顺便说一句,DenyAnonymousAuthorizationRequirement 类是 Microsoft 类,我复制了 IDE 中出现的代码,只是为了在这里发帖。

我的自定义 AuthenticationHandler:

  public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
  {
        public TestAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
                               ILoggerFactory logger,
                               UrlEncoder encoder,
                               ISystemClock clock)
            : base(options, logger, encoder, clock) { }

        protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            ClaimsPrincipal fakeUser = FakeUserUtil.FakeUser();
            var ticket = new AuthenticationTicket(fakeUser, "Test");
            var result = AuthenticateResult.Success(ticket);
            return Task.FromResult(result);
        }
  }

授权要求:

public class DenyAnonymousAuthorizationRequirement : AuthorizationHandler<DenyAnonymousAuthorizationRequirement>, IAuthorizationRequirement
    {

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DenyAnonymousAuthorizationRequirement requirement)
        {
            var user = context.User;
            var userIsAnonymous =
                user?.Identity == null ||
                !user.Identities.Any(i => i.IsAuthenticated);
            if (!userIsAnonymous)
            {
                context.Succeed(requirement);
            }
            return Task.CompletedTask;
        }
    }

使用上述类的ConfigureServices方法中的代码:

 public void ConfigureServices(IServiceCollection services)
 {

            services.AddAuthentication("Test")
                    .AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", null);
            services.AddAuthorization(configure =>
            {
                var builder = new AuthorizationPolicyBuilder(new List<string> {"Test"}.ToArray())
                    .AddRequirements(new DenyAnonymousAuthorizationRequirement());
                configure.DefaultPolicy = builder.Build();
            });
            services.AddControllers()
                    .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                    .AddNewtonsoftJson(options =>
                                           options.SerializerSettings.ReferenceLoopHandling =
                                               ReferenceLoopHandling.Ignore);

}

【问题讨论】:

标签: c# asp.net integration-testing


【解决方案1】:

有相关问题,偶然发现这篇文章here

它表明您可以通过这种方式覆盖在 HttpContext 中设置的用户:

class FakeUserFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        context.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, "123"),
            new Claim(ClaimTypes.Name, "Test user"),
            new Claim(ClaimTypes.Email, "test@example.com"),
            new Claim(ClaimTypes.Role, "Admin")
        }));

        await next();
    }
}

然后将其注入到 ConfigureTestServices 中:

builder.ConfigureTestServices(services =>
        {
            services.AddMvc(options =>
            {                   
                options.Filters.Add(new AllowAnonymousFilter());
                options.Filters.Add(new FakeUserFilter());
            })
            .AddApplicationPart(typeof(Startup).Assembly);
        });

希望对你有帮助

【讨论】:

【解决方案2】:

在“模拟身份验证”会话中查看此文档https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1。我认为您需要在创建客户端后添加此代码:

client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Test");

【讨论】:

猜你喜欢
  • 2019-12-25
  • 2020-02-04
  • 2017-03-14
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
相关资源
最近更新 更多