API密钥保持为空

时间:2017-04-10 12:22:33

标签: servicestack

我指的是this question。我尝试创建一个服务器帐户,如果它在服务器启动时不存在。我已覆盖OnAfterInit来执行此操作。不幸的是,没有创建密钥,更糟糕的是,我的ApiKeyAuthProvider似乎是空的!这是代码:

public class AppHost : AppHostHttpListenerBase
{
    private PooledRedisClientManager RedisBusPool { get; set; }

    public override void Configure(Container container)
    {
        RedisBusPool = new PooledRedisClientManager(connStrBus);

        #region IOC registrations
        container.Register<IRedisClientsManager>(c => new PooledRedisClientManager(connStrBus));
        container.Register(c => new RedisAuthRepository(RedisBusPool));
        //...
        #endregion


        #region ServiceStack plugins
        Plugins.Add(new AuthFeature(() => new AuthUserSession(), 
            new IAuthProvider[] {
                new BediCredentialsAuthProvider(),
                new ApiKeyAuthProvider(AppSettings)
                {
                    KeyTypes = new []{"secret", "publishable"},
                },
            }
        ));
        //...

        #endregion
        //...
    }

    public override void OnAfterInit()
    {
        #region Add test users
        var authRepo = TryResolve<RedisAuthRepository>();
        var user = authRepo.GetUserAuthByUserName("JoeTest");
        if (user == null)
        {
            var newUser = new UserAuth();
            newUser.UserName = "JoeTest";
            newUser.Email = "Joe@test.com";
            newUser.FirstName = "Joe";
            newUser.LastName = "Test";
            user = authRepo.CreateUserAuth(newUser, "topSecret!");
        }

        var keys = authRepo.GetUserApiKeys(user.Id.ToString());
        foreach (var apiKey in keys)
        {
            Debug.WriteLine(apiKey);
        }

        //CANT GET THE AUTHPROVIDER IT IS ALWAYS NULL HERE
        var authProvider = (ApiKeyAuthProvider)AuthenticateService.GetAuthProvider(ApiKeyAuthProvider.Name);


        #endregion
        base.OnAfterInit();
    }

}

用密码,盐等成功创建了用户。以下是我的Redis数据库显示的内容:

{
  "__type": "ServiceStack.Auth.UserAuth, ServiceStack",
  "Id": 2,
  "UserName": "JoeTest",
  "Email": "Joe@test.com",
  "FirstName": "Joe",
  "LastName": "Test",
  "Salt": "1/696g==",
  "PasswordHash": "FZNI5cR5TWTpbvvm9PDy/w/JdRZImQYU5m5P6z8j7TY=",
  "DigestHa1Hash": "e4e0cff88386c6f991d13a3802ce7b53",
  "Roles": [],
  "Permissions": [],
  "CreatedDate": "\/Date(1491811177540)\/",
  "ModifiedDate": "\/Date(1491811177540)\/",
  "InvalidLoginAttempts": 0
}

问题:

  1. 如何创建API密钥?我缺少什么,或者这只适用于启用RegistrationFeature的情况?如果是这样,我该如何保护它(在我的场景中不允许自我注册)以及如何在我的服务初始化后使用它?
  2. 我正在浏览RedisAuthRepository.cs的代码,发现了这个:

    var saltedHash = HostContext.Resolve<IHashProvider>();

  3. 这是否意味着我可以实现并插入我自己的HashProvider?如果是这样,那该怎么办?

    更新

    我发现我可以分配密钥,但前提是我将代码放入AfterInitCallbacks.Add。它似乎被称为AFTER OnAfterInit()

    因此,此代码为ServiceStartup期间生成的帐户创建密钥:

    AfterInitCallbacks.Add(host =>
    {
    
        var authProvider = (ApiKeyAuthProvider)AuthenticateService.GetAuthProvider(ApiKeyAuthProvider.Name);
        var authRepo = (IManageApiKeys)TryResolve<RedisAuthRepository>();
        var userRepo = (IUserAuthRepository)TryResolve<RedisAuthRepository>();
        var user = userRepo.GetUserAuthByUserName("JoeTest");
    
        var keys = authRepo.GetUserApiKeys(user.Id.ToString());
        if (keys.Count == 0)
        {
            try
            {
                keys = authProvider.GenerateNewApiKeys(user.Id.ToString());
                authRepo.StoreAll(keys);
    
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                throw;
            }
        }
    });
    

    至少我可以看到Redis现在生成了什么。但是我仍然不清楚如何自动创建密钥

1 个答案:

答案 0 :(得分:1)

首先,您还应该只有一个PooledRedisClientManager单例实例将所有连接汇集在一起​​,因此您还应该更改Redis Client Manager连接以重用相同的实例,例如:

container.Register<IRedisClientsManager>(c => RedisBusPool);

用户身份验证存储库应该在IAuthRepository界面注册,以便解决,因此您需要将其更改为:

container.Register<IAuthRepository>(c => new RedisAuthRepository(RedisBusPool));

您现在使用以下内容检索:

var authRepo = (IUserAuthRepository)TryResolve<IAuthRepository>();

至于检索ApiKeyAuthProvider,我确认这是按预期工作的:

 var authProvider = (ApiKeyAuthProvider)
     AuthenticateService.GetAuthProvider(ApiKeyAuthProvider.Name);

如果您已在AuthFeature中注册ApiKeyAuthProvider,则应退回。我会仔细检查Null参考错误是否由于另一个问题而导致。