Razor Pages .NET Core 2.1集成测试身份验证 [英] Razor Pages .NET Core 2.1 Integration Testing post authentication

查看:110
本文介绍了Razor Pages .NET Core 2.1集成测试身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一些指导...

I am looking for some guidance...

我目前正在尝试为.net core 2.1中的Razor Pages应用编写一些集成测试,我想测试的页面是后期身份验证,但是我不确定实现该方法的最佳方法.该文档似乎建议创建一个CustomWebApplicationFactory,但除此之外,我还有些迷茫,因为我无法使用基于Cookie的基本身份验证来伪造/模拟已身份验证的用户/请求.

I'm currently looking at trying to write some integration tests for a Razor Pages app in .net core 2.1, the pages I'm wanting to test are post authentication but I'm not sure about the best way of approaching it. The docs seem to suggest creating a CustomWebApplicationFactory, but apart from that I've got a little bit lost as how I can fake/mock an authenticated user/request, using basic cookie based authentication.

我已经看到有一个开放的 GitHub问题(这是实际的 GitHub问题),其中提到了使用IdentityServer4的解决方案,但我只是在寻找如何使用基于cookie的身份验证来做到这一点.

I've seen that there is an open GitHub issue against the Microsoft docs (here is the actual GitHub issue), there was a mentioned solution using IdentityServer4 but I’m just looking how to do this just using cookie based authentication.

有人得到了他们可能会建议的指导吗?

Has anyone got any guidance they may be able to suggest?

预先感谢

到目前为止,我的代码是:

My Code so far is:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
        {
            services.AddDbContext<ApplicationDbContext>(options =>
            {
                options.UseMySql(connectionString);
                options.EnableSensitiveDataLogging();
            });

            services.AddLogging(builder =>
            {
                builder.AddSeq();
            });

            services.ConfigureAuthentication();
            services.ConfigureRouting();
    }
}

ConfigureAuthentication.cs

  namespace MyCarparks.Configuration.Startup
  {
      public static partial class ConfigurationExtensions
      {
          public static IServiceCollection ConfigureAuthentication(this IServiceCollection services)
          {
              services.AddIdentity<MyCarparksUser, IdentityRole>(cfg =>
              {
                  //cfg.SignIn.RequireConfirmedEmail = true;
              })
              .AddDefaultUI()
              .AddDefaultTokenProviders()
              .AddEntityFrameworkStores<ApplicationDbContext>();

              services.ConfigureApplicationCookie(options =>
              {
                  options.LoginPath = $"/Identity/Account/Login";
                  options.LogoutPath = $"/Identity/Account/Logout";
                  options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
              });

              services.AddMvc()
                  .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                  .AddRazorPagesOptions(options =>
              {
                    options.AllowAreas = true;
                    options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
                    options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");

                    options.Conventions.AuthorizeFolder("/Sites");
                });

            return services;
        }
    }
}

集成测试

Integration Tests

PageTests.cs

namespace MyCarparks.Web.IntegrationTests
{
    public class PageTests : IClassFixture<CustomWebApplicationFactory<Startup>>
    {
        private readonly CustomWebApplicationFactory<Startup> factory;

        public PageTests(CustomWebApplicationFactory<Startup> webApplicationFactory)
        {
            factory = webApplicationFactory;
        }


    [Fact]
    public async Task SitesReturnsSuccessAndCorrectContentTypeAndSummary()
    {
        var siteId = Guid.NewGuid();
        var site = new Site { Id = siteId, Address = "Test site address" };
        var mockSite = new Mock<ISitesRepository>();
        mockSite.Setup(s => s.GetSiteById(It.IsAny<Guid>())).ReturnsAsync(site);

        // Arrange
        var client = factory.CreateClient();

        // Act
        var response = await client.GetAsync("http://localhost:44318/sites/sitedetails?siteId=" + siteId);

        // Assert
        response.EnsureSuccessStatusCode();

        response.Content.Headers.ContentType.ToString()
            .Should().Be("text/html; charset=utf-8");

        var responseString = await response.Content.ReadAsStringAsync();
        responseString.Should().Contain("Site Details - MyCarparks");
    }

    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseStartup<Startup>();
        }
    }
}

推荐答案

要实现您的要求,您可以尝试下面的代码,该代码使用身份验证cookie创建客户端.

For implement your requirement, you could try code below which creates the client with the authentication cookies.

    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;
    }
}

这篇关于Razor Pages .NET Core 2.1集成测试身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆