如何解决如何在集成测试中为 HttpContext.User.IsInRole 方法检查声明角色?
TestAuthenticationHandler
此处理程序正在设置名为 John Doe 的测试用户
public class TestAuthenticationSchemeOptions : AuthenticationSchemeOptions
{
public string Role { get; set; }
}
public class TestAuthenticationHandler : AuthenticationHandler<TestAuthenticationSchemeOptions>
{
public TestAuthenticationHandler(IOptionsMonitor<TestAuthenticationSchemeOptions> options,ILoggerFactory logger,UrlEncoder encoder,ISystemClock clock)
: base(options,logger,encoder,clock)
{
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var claims = new[]
{
new Claim(ClaimTypes.Name,"Test"),new Claim(ClaimTypes.NameIdentifier,Guid.NewGuid().ToString()),new Claim("MemberId",Options.Role),new Claim("MemberForename","John"),new Claim("MemberSurname","Doe")
};
var identity = new ClaimsIdentity(claims,"Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal,"Test");
var result = AuthenticateResult.Success(ticket);
return Task.Fromresult(result);
}
}
测试方法
[Theory]
[InlineData("/home/index")]
public async Task GetServerSideRenderedPage_ReturnsOk(string url)
{
// Arrange
HttpClient client = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication("Test")
.AddScheme<TestAuthenticationSchemeOptions,TestAuthenticationHandler>("Test",options => options.Role = "Admin");
});
}).CreateClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Test");
// Act
var response = await client.GetAsync(url);
// Assert
Assert.Equal(HttpStatusCode.OK,response.StatusCode);
Assert.NotNull(response.Content);
Assert.Equal("text/html",response.Content.Headers.ContentType.MediaType);
Assert.True(response.Content.Headers.ContentLength > 0);
}
Startup.cs
启用身份验证(生产中不需要)
app.UseAuthentication();
我需要测试的控制器动作
在生产中 HttpContext
不是 NULL,但在测试中它是 NULL。所以我不得不添加通过 IHttpContextAccessor
填充的 AuthenticationHandler
(HttpContext
仍然是 NULL,但 IHttpContextAccessor.HttpContext
是可以的)
public class HomeController : Controller
{
private readonly IHttpContextAccessor _httpContext;
public HomeController(IHttpContextAccessor httpContext)
{
_httpContext = httpContext;
}
[HttpGet]
public IActionResult Index()
{
var allowed = _httpContext.HttpContext.User.IsInRole("Admin");
return View();
}
}
我面临的问题是 allowed
属性为 false
,但我向用户声明了 Admin 角色。
在生产中它有效,因为应用程序在 IIS 服务器上运行并且管理员角色(在生产中命名不同)是域安全组。所以 HttpContext
正在检查连接的用户是否是域组的成员,但我不知道如何在测试中伪造/模拟 IsInRole()
方法。我是否必须在 TestAuthenticationHandler
中添加一些额外的声明?
此处描述的设置在使用 [Authorize(Roles = "Admin")]
属性时有效,但我也需要使用 IsInRole()
方法。
你有什么想法吗?
解决方案
这里缺少的部分是特定的角色声明
var claims = new[]
{
new Claim(ClaimTypes.Name,new Claim(ClaimTypes.Role,// <-- this line was missing
new Claim("MemberId","Doe")
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。