使用API密钥验证服务器到服务器的通信 [英] Authenticate server to server communication with API key
问题描述
我有两个自托管的Windows服务与ServiceStack一起运行。这些服务由许多WPF和WinForms客户端应用程序使用。
我写了自己的CredentialsAuthProvider
。我的第一个用户数据库实现是在使用NHibernate的MSSQL服务器上。现在,由于系统在增长,我对事情进行了一些重组。我创建了一个中央"基础设施"服务,它使用Redis作为数据存储,负责帐户管理、中央配置和首选项管理。稍后,它还将包含中央日志记录和RedisMQ。所有帐户、角色等现在都存储在那里(而不是MSSQL)。帐户迁移已成功,到目前为止身份验证工作正常。
现在我遇到了一个问题,即客户端和服务器需要获取并设置它们的配置/首选项。这意味着我的服务器也是客户端,因为它们不仅为其特定业务域的客户端请求提供服务,而且本身还需要调用"基础结构"服务器来加载/更新自己的配置以及以后的日志条目和消息。
要对此类请求进行身份验证,我认为使用API密钥是一种很好的方法。这些请求与用户无关,因此不需要网关功能,它们只需要与中央基础结构服务器进行一些通信。因此,我正在阅读有关API Key Provider的ServiceStack文档,但不幸的是,对我来说,许多内容仍然不清楚。
这里首先是我的‘Infrastructure’服务器的Configure
方法中的一些相关代码:
private PooledRedisClientManager RedisBusinessPool { get; set; }
//...
container.Register<IRedisClientsManager>(c => new PooledRedisClientManager(connStrBus));
container.Register(c => new AppUserRepository(RedisBusinessPool));
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new BediCredentialsAuthProvider(),
}
));
// For the API keys I tried:
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings)
{
KeyTypes = new []{"secret", "publishable"},
},
}
));
因为我启用了API密钥插件,所以当我尝试登录时在客户端收到错误:
ERROR; AccountManagerWinDesktop; [LoginViewModel+<Login>d__50.MoveNext]; - <username> failed to login to server <myInfrastructureServer>. Exception: 404 NotFound
Code: NotFound, Message: No configuration was added for OAuth provider 'credentials'
这是否意味着我必须实现我自己的ApiKeyProvider
以配合我的CredentialAuthProvider
的实现?如果是,我需要添加什么?
CredentialAuthProvider
实现中,我覆盖了Logout
、Authenticate
、OnAuthenticated
和TryAuthenticate
。WPF客户端提供了一个用于存储用户和角色的UI。它们存储在Redis数据库中,包括散列密码等。
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
AppUser user = null;
try
{
//the repository handles all Redis database access
var userRepo = HostContext.TryResolve<AppUserRepository>();
user = userRepo.GetAppUser(userName);
if (user == null)
throw HttpError.NotFound("User '{0}' not found. Please try again.".Fmt(userName));
authService.Request.Items.Add("AppUser", user);
var pwdMgr = new PwdManager();
var hpwd = pwdMgr.GetHashedPassword(password, user.Salt);
if (hpwd == user.Password)
{
//do stuff
}
else
{
// do other stuff
}
return hpwd == user.Password;
}
catch (Exception ex)
{
Log.Error($"Error retrieving user {user} to authenticate. Error: {ex}");
throw;
}
}
我现在不明白的-问题:
- API密钥与我自己的CredentialsAuthProvider实现有什么关系?
- 如何向应用程序服务器颁发API密钥?(我读到ServiceStack在创建用户时自动创建密钥,但在我的场景中不需要这样做)
- 我是否也必须实现我自己的
ApiKeyAuthProvider
,类似于我已覆盖的CredentialsAuthProvider
?如果有,有没有样品? - 是否有API密钥的对象/数据模型?
- 我是否需要实现类似上面的
TryAuthenticate
方法来验证我的API密钥?
推荐答案
您应该只注册任何插件类型的1,因此更改您的AuthFeature
插件以注册您要启用的所有身份验证提供程序,例如:
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new BediCredentialsAuthProvider(),
new ApiKeyAuthProvider(AppSettings)
{
KeyTypes = new []{"secret", "publishable"},
},
}
));
- API密钥与我自己的CredentialsAuthProvider实现有什么关系?
将API密钥分配给用户,即,当使用API密钥接收到请求时,他们将作为分配了API密钥的用户进行身份验证。API密钥是为每个注册的新用户创建的,上面的配置为使用/register
服务创建的新注册表创建了秘密和可发布密钥。
API密钥需要使用用户身份验证存储库
您的用户需要persisted in an AuthRepository才能使用API密钥AuthProvider。文档中列出了support Auth Repositories的列表。尽管您可以使用您自己的自定义用户身份验证存储库(如果它实现了IUserAuthRepository
和IManableApiKeys
接口)。
- 如何向应用服务器下发API密钥?(我读到ServiceStack在创建用户时自动创建密钥,但在我的场景中不需要这样做)
将API密钥分配给用户-所有ServiceStack AuthProvider都围绕对用户进行身份验证。一种想法是创建一个"用户"来表示该App Server。您可以使用IManageApiKeys API创建您自己的API密钥,code-snippet for creating API Keys for existing Users中有一个使用该密钥的示例。
- 我是否还必须实现我自己的ApiKeyAuthProvider,类似于我覆盖的CredentialsAuthProvider?如果有,有没有样品?
您不需要实现任何内容即可使用现有的ApiKeyAuthProvider
,但如果它无法执行您所需的操作,您可以获取ApiKeyAuthProvider.cs并创建一个可执行您所需操作的自定义版本。
- 是否有API密钥的对象/数据模型?
ApiKey类是包含API密钥本身的模型,它保存在所有supported Auth Repositories中。
- 我是否需要实现类似上面的TryAuthenticate方法来验证我的API密钥?
否
这篇关于使用API密钥验证服务器到服务器的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!