全局设置经过身份验证的用户,以便在ASP.NET Core中进行测试

时间:2019-02-11 18:21:07

标签: asp.net-core asp.net-core-identity

我正在使用带有ASP.Net Core Identity项目的ASP.NET Core 2.2。

我想全局设置经过身份验证的用户及其UserId进行测试。

有可能吗?

1 个答案:

答案 0 :(得分:1)

对于集成测试,您可以以程序方式登录应用程序,保存cookie,然后将cookie附加到子请求中。

尝试实现自定义WebApplicationFactory

public class CustomWebApplicationFactory<TEntryPoint> : WebApplicationFactory<TEntryPoint> where TEntryPoint : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {

        });
        base.ConfigureWebHost(builder);
    }
    public new HttpClient CreateClient()
    {
        var cookieContainer = new CookieContainer();
        var uri = new Uri("https://localhost:44344/Identity/Account/Login");
        var httpClientHandler = new HttpClientHandler
        {
            CookieContainer = cookieContainer
        };
        HttpClient httpClient = new HttpClient(httpClientHandler);
        var verificationToken = GetVerificationToken(httpClient, "https://localhost:44344/Identity/Account/Login");
        var contentToSend = new FormUrlEncodedContent(new[]
                {
                            new KeyValuePair<string, string>("Email", "test@outlook.com"),
                            new KeyValuePair<string, string>("Password", "1qaz@WSX"),
                            new KeyValuePair<string, string>("__RequestVerificationToken", verificationToken),
                        });
        var response = httpClient.PostAsync("https://localhost:44344/Identity/Account/Login", contentToSend).Result;
        var cookies = cookieContainer.GetCookies(new Uri("https://localhost:44344/Identity/Account/Login"));
        cookieContainer.Add(cookies);
        var client = new HttpClient(httpClientHandler);
        return client;
    }
    private string GetVerificationToken(HttpClient client, string url)
    {
        HttpResponseMessage response = client.GetAsync(url).Result;
        var verificationToken =response.Content.ReadAsStringAsync().Result;
        if (verificationToken != null && verificationToken.Length > 0)
        {
            verificationToken = verificationToken.Substring(verificationToken.IndexOf("__RequestVerificationToken"));
            verificationToken = verificationToken.Substring(verificationToken.IndexOf("value=\"") + 7);
            verificationToken = verificationToken.Substring(0, verificationToken.IndexOf("\""));
        }
        return verificationToken;
    }
}

然后

public class IntegrationTestWithIdentityTest : IClassFixture<CustomWebApplicationFactory<Startup>>
{
    private readonly HttpClient _client;
    private readonly CustomWebApplicationFactory<Startup> _factory;

    public IntegrationTestWithIdentityTest(CustomWebApplicationFactory<Startup> factory)
    {

        _factory = factory;
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task IndexRendersCorrectTitle()
    {
        var response = await _client.GetAsync("https://localhost:44344/About");

        response.EnsureSuccessStatusCode();

        var responseString = await response.Content.ReadAsStringAsync();

        Assert.Contains("Send Email", responseString);
    }        

}

源代码:IntegrationTestWithIdentityTest

如果要模拟身份表中不存在的用户,则需要定义一个新端点,该端点将使用

对用户进行签名
public async Task<IActionResult> Login()
{
    var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "edward"));
    identity.AddClaim(new Claim(ClaimTypes.Name, "edward zhou"));
    //add your own claims from jwt token
    var principal = new ClaimsPrincipal(identity);
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = true });            
    return View();
}