运行 在 apphost 上进行基本身份验证测试时出现 400 错误

Getting 400 error when running basic auth test on apphost

我有一个应用主机

    public class LocalTestAppHost : AppSelfHostBase
    {
        public LocalTestAppHost() : base(nameof(LocalTestAppHost), typeof(MyServices).Assembly, typeof(LocalTestAppHost).Assembly) { }


        public override void Configure(Container container)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                // .AddJsonFile("appSettings.json")
                .AddEnvironmentVariables()
                .AddUserSecrets(typeof(IntegrationTest).Assembly);
            
            var configuration = builder.Build();
            
            AppSettings = new NetCoreAppSettings(configuration);

            container.AddSingleton<IAppSettings>(AppSettings);

            SetConfig(new HostConfig
            {
                AddRedirectParamsToQueryString = true,
                DebugMode = true
            });
            
            Plugins.Add(new CorsFeature(allowOriginWhitelist: new[] { IntegrationTestBase.BaseUriLocalDev },
                allowedMethods: "GET, PATCH, POST, PUT, DELETE, OPTIONS",
                allowCredentials: true,
                allowedHeaders: "Content-Type, Allow, Authorization"));
            
            JsConfig.DateHandler = DateHandler.ISO8601;
            
            var connectionString = AppSettings.GetString("DefaultConnection");

            OrmLiteConfig.StripUpperInLike = false;

            container.AddSingleton<IDbConnectionFactory>(new OrmLiteConnectionFactory(connectionString, PostgreSqlDialect.Provider));
            
            container.AddSingleton<IAuthRepository>(c =>
                new OrmLiteAuthRepository<UserAuthCustom, UserAuthDetails>(c.Resolve<IDbConnectionFactory>())
                {
                    UseDistinctRoleTables = true
                });
            
            Plugins.Add(new AuthFeature(() => new CustomUserSession(),
                new IAuthProvider[] {
                    new CredentialsAuthProvider(AppSettings)
                    {
                        
                    },     /* Sign In with Username / Password credentials */
                }));
            
            Plugins.Add(new AdminUsersFeature());
            
            
        }
    }

我正在尝试 运行 我登录的地方进行简单测试(使用与本地数据库的现有连接)

    public class ReportTests : IntegrationTestBase
    {
        private string _adminUser;
        private string _adminPass;
        public ReportTests()
        {
            Licensing.RegisterLicense(Licence);
            this.AppHost = new LocalTestAppHost()
                .Init()
                .Start(BaseUriLocalDev); 
            
            Settings = AppHost.Resolve<IAppSettings>();
            Db = AppHost.Resolve<IDbConnectionFactory>().OpenDbConnection();

            _adminUser = Settings.GetString("adminUser");
            _adminPass = Settings.GetString("adminPass");
        }

        [Test]
        public void TestStats()
        {
            var users = Db.Select<UserAuthCustom>();
            var client = new JsonServiceClient(BaseUriLocalDev);

            var authReq = new Authenticate()
            {
                UserName = _adminUser,
                Password = _adminPass,
                provider = CredentialsAuthProvider.Name
            };

            var resp = client.Post(authReq);
        }

但是它抛出这个异常:

System.Net.WebException: Received an invalid status line: '400'.
 ---> System.Net.Http.HttpRequestException: Received an invalid status line: '400'.
   at System.Net.Http.HttpConnection.ParseStatusLine(Span`1 line, HttpResponseMessage response)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.SocketsHttpHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClientHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.HttpWebRequest.SendRequest(Boolean async)
   at System.Net.HttpWebRequest.GetResponse()
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetResponse()
   at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:line 1416
   at ServiceStack.ServiceClientBase.Post[TResponse](IReturn`1 requestDto) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack.Client\ServiceClientBase.cs:line 1581
   at LeadInput.Tests.IntegrationTests.ReportTests.TestStats() in D:\Clients\LeadInput\LeadInput.Tests\IntegrationTests\ReportTests.cs:line 43

我正在努力弄清楚为什么它不起作用以及为什么它没有收到来自应用程序主机的有效响应。

作为 apphost 只有 运行 的测试范围,我发现很难调试。似乎一切都是正确的,但我得到的回复无效。

单步执行代码 client.GetResponse(); 抛出异常,我猜它的格式是意外的,但我看不到在调试器中获取原始响应的方法。

我哪里出错了?

编辑

它也发生在 hello world 端点上,所以我猜 AppHost 不是 运行ning。我试过更改端口但没有帮助。我最近升级到 5.13.3,不确定是否相关。

编辑

调试器处于活动状态时,记录如下:

DEBUG: CreateRequestAsync/requestParams: WARN: Could not Set-Cookie 'ss-id': Could not load type 'Microsoft.Extensions.Primitives.InplaceStringBuilder' from assembly 'Microsoft.Extensions.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'., Exception: Could not load type 'Microsoft.Extensions.Primitives.InplaceStringBuilder' from assembly 'Microsoft.Extensions.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

您可以尝试在您的 AppHost 中启用调试日志记录以查看是否记录任何信息:

LogManager.LogFactory = new ConsoleLogFactory(debugEnabled:true); 

不要忘记您的 Integration test 需要在 运行 之后处理 AppHost,否则其他集成测试将失败:

[OneTimeTearDown]
public void OneTimeTearDown() => AppHost.Dispose();

查看响应的一种方法是 运行 您的 AppHost 很长一段时间,然后您可以通过检查外部 HTTP 请求来查看输出,例如通过 Chrome 的 WebInspector 或 curl:

[Test]
public void Run_for_30secs()
{
    Thread.Sleep(30000);
}

听起来好像 AppHost 不正确 运行ning,所以我会 comment/disable 功能,直到你能找出问题。

Note: CORS isn't relevant in an integration test, it's only relevant when called from a Web browser making cross-domain requests.