英文:
How to override program.cs to disable authentication and authorization for ASP.NET Core Razor Pages web app?
问题
I have this test class that fails with an error.
> System.Net.Http.HttpRequestException : Response status code does not
> indicate success: 302 (Found).
If I manually commented out the code for authentication and authorization in program.cs
, the test class works as expected.
In program.cs (I am using .NET 6):
//builder.Services.AddRazorPages()
// .AddRazorPagesOptions(options => {
// options.Conventions.AuthorizeFolder("/"); // apply the [Authorize] attribute to all pages for all folders
// })
// .AddMicrosoftIdentityUI();
builder.Services.AddRazorPages();
How to override program.cs
in my test class to disable authentication and authorization for ASP.NET Core Razor Pages web app?
This is my test class:
public class IntegrationTests : IClassFixture<WebApplicationFactory<Program>> {
private readonly WebApplicationFactory<Program> _factory;
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.AddRazorPages();
});
});
}
[Theory]
[InlineData("/")]
public async Task Get_EndpointsReturnSecurePageAsync(string url) {
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync(url);
// Assert
response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal("text/html; charset=utf-8",
response.Content.Headers.ContentType.ToString());
}
}
英文:
I have this test class that fails with an error.
> System.Net.Http.HttpRequestException : Response status code does not
> indicate success: 302 (Found).
If I manually commented out the code for authentication and authorization in program.cs
, the test class works as expected.
In program.cs (I am using .NET 6):
//builder.Services.AddRazorPages()
// .AddRazorPagesOptions(options => {
// options.Conventions.AuthorizeFolder("/"); // apply the [Authorize] attribute to all pages for all folders
// })
// .AddMicrosoftIdentityUI();
builder.Services.AddRazorPages();
How to override program.cs
in my test class to disable authentication and authorization for ASP.NET Core Razor Pages web app?
This is my test class:
public class IntegrationTests : IClassFixture<WebApplicationFactory<Program>> {
private readonly WebApplicationFactory<Program> _factory;
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.AddRazorPages();
});
});
}
[Theory]
[InlineData("/")]
public async Task Get_EndpointsReturnSecurePageAsync(string url) {
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync(url);
// Assert
response.EnsureSuccessStatusCode(); // Status Code 200-299
Assert.Equal("text/html; charset=utf-8",
response.Content.Headers.ContentType.ToString());
}
}
答案1
得分: 5
从ASP.NET Core集成测试中的文档-模拟身份验证中的文档:
测试应用程序可以在ConfigureTestServices中模拟AuthenticationHandler<TOptions>以测试身份验证和授权的方面。
在上述链接中提供了代码示例:
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()
{
var claims = new[] { new Claim(ClaimTypes.Name, "Test user") };
var identity = new ClaimsIdentity(claims, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "TestScheme");
var result = AuthenticateResult.Success(ticket);
return Task.FromResult(result);
}
}
将身份验证处理程序添加到测试中使用的服务集合:
[Fact]
public async Task Get_SecurePageIsReturnedForAnAuthenticatedUser()
{
// Arrange
var client = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication(defaultScheme: "TestScheme")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
"TestScheme", options => { });
});
})
.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(scheme: "TestScheme");
//Act
var response = await client.GetAsync("/SecurePage");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
英文:
From the documentation at Integration tests in ASP.NET Core - Mock authentication
> The test app can mock an AuthenticationHandler<TOptions> in ConfigureTestServices in order to test aspects of authentication and authorization.
Code examples given in the above link:
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()
{
var claims = new[] { new Claim(ClaimTypes.Name, "Test user") };
var identity = new ClaimsIdentity(claims, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "TestScheme");
var result = AuthenticateResult.Success(ticket);
return Task.FromResult(result);
}
}
Add the authentication handler to the services collection used in the test:
[Fact]
public async Task Get_SecurePageIsReturnedForAnAuthenticatedUser()
{
// Arrange
var client = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication(defaultScheme: "TestScheme")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
"TestScheme", options => { });
});
})
.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(scheme: "TestScheme");
//Act
var response = await client.GetAsync("/SecurePage");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
答案2
得分: 1
你可以尝试在调用AddRazorPages
之前移除配置的RazorPagesOptions
选项:
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.RemoveAll<IConfigureOptions<RazorPagesOptions>>();
services.AddRazorPages().AddRazorPagesOptions(_ => {});
});
});
}
或者:
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.RemoveAll<IConfigureOptions<RazorPagesOptions>>();
services.AddRazorPages();
});
});
}
英文:
You can try removing the configured RazorPagesOptions
options before calling the AddRazorPages
:
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.RemoveAll<IConfigureOptions<RazorPagesOptions>>();
services.AddRazorPages().AddRazorPagesOptions(_ => {});
});
});
}
Or just:
public IntegrationTests(WebApplicationFactory<Program> factory) {
_factory = factory.WithWebHostBuilder(builder =>
{
// Override the services configuration for testing
builder.ConfigureServices(services =>
{
// Remove the authorization policy for Razor Pages
services.RemoveAll<IConfigureOptions<RazorPagesOptions>>();
services.AddRazorPages();
});
});
}
答案3
得分: 0
使用环境变量来完成。从安全角度看,这有多安全是另一个问题。
检查在 program.cs 中是否设置了该变量:
if (Environment.GetEnvironmentVariable("TEST_NO_AUTH") == "enabled")
{
builder.Services.AddRazorPages();
}
else
{
builder.Services.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/"); // apply the [Authorize] attribute to all pages for all folders
})
.AddMicrosoftIdentityUI();
}
然后在测试构造函数中设置该变量:
Environment.SetEnvironmentVariable("TEST_NO_AUTH", "enabled");
英文:
Using an environment variable will do it. How safe this is from a security perspective is another question.
Check if the variable is set in program.cs:
if (Environment.GetEnvironmentVariable("TEST_NO_AUTH") == "enabled")
{
builder.Services.AddRazorPages();
}
else
{
builder.Services.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/"); // apply the [Authorize] attribute to all pages for all folders
})
.AddMicrosoftIdentityUI();
}
Then set the variable in the tests constructor.
Environment.SetEnvironmentVariable("TEST_NO_AUTH", "enabled");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论