You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ServiceStack集成测试中认证失败问题求助

问题

我搭建了一个带有认证功能的ServiceStack项目,为其中一个服务添加了[Authenticate]特性。启动应用后登录并执行服务时,认证流程可正常工作,但在集成测试中调用服务始终返回Unauthorized响应,认证失败。以下是我的集成测试代码:

public class IntegrationTest
{
    const string BaseUri = "http://localhost:2000/";
    private readonly ServiceStackHost appHost;

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

        public override void Configure(Container container)
        {
            container.Register<IDbConnectionFactory>(c =>
                new OrmLiteConnectionFactory("Server=*redacted*;User Id=*redacted*;Password=*redacted*;..."));
            container.Register<IAuthRepository>(c =>
                new OrmLiteAuthRepository<Framework.Types.AppUser, UserAuthDetails>(c.Resolve<IDbConnectionFactory>())
                {
                    UseDistinctRoleTables = true
                });

            Plugins.Add(new AuthFeature(() => new Framework.Types.TenantUserSession(),
                    new IAuthProvider[] {
                        new CredentialsAuthProvider(AppSettings),     /* Sign In with Username / Password credentials */
                    }));


            var authRepo = container.Resolve<IAuthRepository>();
            authRepo.InitSchema();
            CreateUser(authRepo, "admin@email.com", "Admin User", "p@55wOrd", roles:new[]{ RoleNames.Admin });
        }
    }

    static void CreateUser(IAuthRepository authRepo, string email, string name, string password, string[] roles)
    {
        if (authRepo.GetUserAuthByUserName(email) == null)
        {
            var newAdmin = new Framework.Types.AppUser { Email = email, DisplayName = name };
            var user = authRepo.CreateUserAuth(newAdmin, password);
            authRepo.AssignRoles(user, roles);
        }
    }
    
    public IntegrationTest()
    {
        appHost = new AppHost()
            .Init()
            .Start(BaseUri);
    }

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

    //Create the client with username and password of created user.
    public IServiceClient CreateClient() => new JsonServiceClient(BaseUri) { UserName = "admin@email.com", Password = "p@55wOrd" };

    [Test]
    public async Task Can_execute_authenticated_operation()
    {
        var client = CreateClient();

        var response = await client.PostAsync(new Framework.ServiceModel.MetaOperationExecute()); //This line fails with 401 Unauthorized
        Assert.That(response.token, Is.Not.Null);
    }
}
解决方案

问题根源是你设置的UserName和Password不会自动触发ServiceStack客户端的认证流程,客户端不会主动用这些凭据去登录获取有效会话,需要手动完成认证步骤。

以下是几种可行的修复方式:

方式1:在创建客户端时手动完成认证

修改CreateClient方法,添加登录逻辑,确保客户端拿到有效会话:

public IServiceClient CreateClient() 
{
    var client = new JsonServiceClient(BaseUri);
    // 手动调用认证接口,获取会话凭据
    client.Post(new Authenticate {
        UserName = "admin@email.com",
        Password = "p@55wOrd",
        RememberMe = true
    });
    return client;
}

方式2:使用ClientCredentials自动处理认证

ServiceStack客户端支持ClientCredentials属性,设置后会自动在需要时执行认证:

public IServiceClient CreateClient() 
{
    var client = new JsonServiceClient(BaseUri);
    client.ClientCredentials = new NetworkCredential("admin@email.com", "p@55wOrd");
    return client;
}

方式3:在测试方法中先登录再调用服务

如果不想修改CreateClient方法,也可以在测试逻辑里先完成认证:

[Test]
public async Task Can_execute_authenticated_operation()
{
    var client = CreateClient();
    // 先执行登录获取有效会话
    await client.PostAsync(new Authenticate {
        UserName = "admin@email.com",
        Password = "p@55wOrd"
    });
    
    var response = await client.PostAsync(new Framework.ServiceModel.MetaOperationExecute());
    Assert.That(response.token, Is.Not.Null);
}

额外注意事项:

  • 确保你的TenantUserSession继承自ServiceStack的AuthSession,否则无法正确保存认证状态
  • 集成测试建议使用独立的测试数据库,避免和生产环境数据相互干扰

内容的提问来源于stack exchange,提问作者Shawn de Wet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:28:30