如何在 ASP.net 核心集成测试中获得授权(我非常接近)

Posted

技术标签:

【中文标题】如何在 ASP.net 核心集成测试中获得授权(我非常接近)【英文标题】:How do I get Authorization working in ASP.net core integration testing (I'm very close) 【发布时间】:2022-01-17 17:12:24 【问题描述】:

我已关注these instructions 以使身份验证与 ASP.net 核心集成测试一起工作。它几乎可以工作了。我的 HttpContext.User 正确填充了声明。但是我对具有[Authorize] 属性的Web API 控制器的请求仍然失败,除非我指定方案:[Authorize(AuthenticationSchemes = "Test")] 有效。当我在builder.ConfigureTestServices() 方法中添加“Test”作为默认方案时,我很小心地指定它,那么为什么不接受它作为默认方案呢?

builder.ConfigureTestServices(services =>

    /* Overriding policies and adding Test Scheme defined in TestAuthHandler */
    services.AddMvc(options =>
    
        var policy = new AuthorizationPolicyBuilder(new[]  "Test" )
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Test")
            .Build();

        options.Filters.Add(new AuthorizeFilter(policy));
    );

    /* Adding Default Authentication schemes
        This is enough to prevent unauthorized client (if you wish to have that kind of tests) */
    services.AddAuthentication(options =>
    
        options.DefaultAuthenticateScheme = "Test";
        options.DefaultChallengeScheme = "Test";
        options.DefaultScheme = "Test";
        options.DefaultForbidScheme = "Test";
        options.DefaultChallengeScheme = "Test";
        options.DefaultSignInScheme = "Test";
        options.DefaultSignOutScheme = "Test";
    )
    /* Here we're adding TestAuthentication Scheme with Handler that will Authenticate our client based on Claims */
    .AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options =>  );
);

【问题讨论】:

【参考方案1】:

这是一个类似的示例,其中包含两个身份验证方法 JWT 和一个 X-API-KEY 标头。

// MVC or Controllers
services.AddControllers().AddNewtonsoftJson(options => 
  options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
  options.SerializerSettings.ContractResolver = new DefaultContractResolver();
);

// Add your auth methods
services.AddAuthentication()
  .AddJwtBearer(options =>
  
    options.TokenValidationParameters = new TokenValidationParameters()
    
      ValidateIssuer = true,
      ValidateAudience = true,
      ValidateLifetime = true,
      ValidateIssuerSigningKey = true,
      ValidIssuer = Configuration["Jwt:Issuer"],
      ValidAudience = Configuration["Jwt:Audience"],
      IssuerSigningKey = new SymmetricSecurityKey(
          Encoding.UTF8.GetBytes(Configuration["Jwt:Secret"])
      )
    ;
    options.Events = new JwtBearerEvents
    
      // custom validations ip, hash, etc.
      OnTokenValidated = AdditionalValidation
    ;
  )
  // this line is a custom x-api-key header auth method
  .AddApiKeySupport(options => );

现在您必须设置您的授权策略。这就是您的策略无法默认运行的原因。

// Here you need to add your policy
services.AddAuthorization(options => 
  var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
    // Add your scheme here
    JwtBearerDefaults.AuthenticationScheme, 
    ApiKeyAuthenticationOptions.DefaultScheme
  );
  defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
  options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
);
//...
// Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

  //...
  // Add these two lines
  app.UseAuthentication();    
  app.UseAuthorization();
  //...
  app.UseEndpoints(endpoints =>
  
    endpoints.MapControllers();
  );

控制器如下所示:

[HttpGet("tester")]
[Authorize]
public async Task<ActionResult> GetResult()
      
  // your method
  return Ok("ok");

请求示例 1 x-api-key:

请求示例 2 JWT:

【讨论】:

以上是关于如何在 ASP.net 核心集成测试中获得授权(我非常接近)的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET 核心应用中本地模拟 Azure 应用服务授权

为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?

在 asp.net 核心中使用身份时未找到具有授权属性的操作

asp.net 核心中的 JWT 身份验证验证

Asp.net核心身份声明与基于角色的授权[重复]

Angular 4 对 asp.net 核心 API 的请求(在标头中使用授权)不起作用