У меня есть intr anet asp core 3.0 MVC веб-приложение с windows аутентификацией. В Views / Shared / _Layout я вызываю ViewCompent, чтобы получить имя и фамилию текущего пользователя следующим методом:
public Task<string> getNameAsync()
{
return Task.Run<string>(() =>
{
string name = GetNameInSession();
if (name == null || name == "")
{
PrincipalContext pc = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(pc, User.Identity.Name);
name = user.GivenName + " " + user.Surname;
SetNameInSession(name);
}
return name;
});
}
В настоящее время я пытаюсь написать интеграционный тест для своего приложения, но каждый раз, когда он обращается к методу getNameAsyn c (), он выбрасывает нулевое исключение, потому что ContextType.Domain имеет значение null.
Я прочитал в Интернете и нашел способы использования пользовательских идентификаторов для своего теста, так что теперь User. Identity.Name возвращает все, что я хочу, но я не могу найти способ смоделировать или определить пользовательский ContextType.Domain или смоделировать PrincipalContext ... Я подумал, что, возможно, я мог бы использовать ClaimsPrincipal.FindFirstValue (ClaimType.GivenName) вместо использования PrincipalContext но он всегда возвращает ноль.
Вот мой интеграционный тест:
public class BrowseControllerTest : IClassFixture<CustomApplicationFactory<Startup>>
{
protected readonly HttpClient _client;
public BrowseControllerTest(CustomApplicationFactory<Startup> factory)
{
_client = factory.CreateClient();
}
[Theory]
[InlineData(1)]
[InlineData(2)]
public async Task ReturnDomain(int value)
{
var response = await _client.GetAsync("/Browse/Domain/"+value);
response.EnsureSuccessStatusCode();
}
}
Мой CustomApplicationFactory, который позволяет мне использовать тестовую базу данных и идентификацию пользователя:
public class CustomApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Remove the app's ApplicationDbContext registration.
var descriptor = services.SingleOrDefault(
d => d.ServiceType ==
typeof(DbContextOptions<My_DBContext>));
if (descriptor != null)
{
services.Remove(descriptor);
}
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<BRG_DistributionContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
services.AddAuthentication(o =>
{
o.DefaultScheme = "TestScheme";
}).AddCustomAuthentication("TestScheme", "My custom authentication scheme", o => { });
// Build the service provider.
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<BRG_DistributionContext>();
var logger = scopedServices
.GetRequiredService<ILogger<CustomApplicationFactory<TStartup>>>();
// Ensure the database is created.
db.Database.EnsureCreated();
try
{
// Seed the database with test data.
Utilities.InitializeDbForTests(db);
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred seeding the " +
"database with test messages. Error: {Message}", ex.Message);
}
}
});
}
Итак, мой вопрос: как я могу издеваться / определять пользовательский ContextType.Domain или PrincipalContext? Если это невозможно, как я могу получить имя и фамилию текущего пользователя, используя утверждения, если FindFirstValue (ClaimTypes.GivenName) возвращает ноль?