我指的是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
}
问题:
RegistrationFeature
的情况?如果是这样,我该如何保护它(在我的场景中不允许自我注册)以及如何在我的服务初始化后使用它?我正在浏览RedisAuthRepository.cs的代码,发现了这个:
var saltedHash = HostContext.Resolve<IHashProvider>();
这是否意味着我可以实现并插入我自己的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现在生成了什么。但是我仍然不清楚如何自动创建密钥。
答案 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参考错误是否由于另一个问题而导致。