使用API密钥验证服务器到服务器的通信 [英] Authenticate server to server communication with API key

查看:16
本文介绍了使用API密钥验证服务器到服务器的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个自托管的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实现中,我覆盖了LogoutAuthenticateOnAuthenticatedTryAuthenticate。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;
    }
}

我现在不明白的-问题:

  1. API密钥与我自己的CredentialsAuthProvider实现有什么关系?
  2. 如何向应用程序服务器颁发API密钥?(我读到ServiceStack在创建用户时自动创建密钥,但在我的场景中不需要这样做)
  3. 我是否也必须实现我自己的ApiKeyAuthProvider,类似于我已覆盖的CredentialsAuthProvider?如果有,有没有样品?
  4. 是否有API密钥的对象/数据模型?
  5. 我是否需要实现类似上面的TryAuthenticate方法来验证我的API密钥?

推荐答案

您应该只注册任何插件类型的1,因此更改您的AuthFeature插件以注册您要启用的所有身份验证提供程序,例如:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new IAuthProvider[] {
       new BediCredentialsAuthProvider(),
       new ApiKeyAuthProvider(AppSettings)
       {
           KeyTypes = new []{"secret", "publishable"},
       }, 
    }
));
  1. API密钥与我自己的CredentialsAuthProvider实现有什么关系?

将API密钥分配给用户,即,当使用API密钥接收到请求时,他们将作为分配了API密钥的用户进行身份验证。API密钥是为每个注册的新用户创建的,上面的配置为使用/register服务创建的新注册表创建了秘密可发布密钥。

API密钥需要使用用户身份验证存储库

您的用户需要persisted in an AuthRepository才能使用API密钥AuthProvider。文档中列出了support Auth Repositories的列表。尽管您可以使用您自己的自定义用户身份验证存储库(如果它实现了IUserAuthRepositoryIManableApiKeys接口)。

  1. 如何向应用服务器下发API密钥?(我读到ServiceStack在创建用户时自动创建密钥,但在我的场景中不需要这样做)

将API密钥分配给用户-所有ServiceStack AuthProvider都围绕对用户进行身份验证。一种想法是创建一个"用户"来表示该App Server。您可以使用IManageApiKeys API创建您自己的API密钥,code-snippet for creating API Keys for existing Users中有一个使用该密钥的示例。

  1. 我是否还必须实现我自己的ApiKeyAuthProvider,类似于我覆盖的CredentialsAuthProvider?如果有,有没有样品?

您不需要实现任何内容即可使用现有的ApiKeyAuthProvider,但如果它无法执行您所需的操作,您可以获取ApiKeyAuthProvider.cs并创建一个可执行您所需操作的自定义版本。

  1. 是否有API密钥的对象/数据模型?

ApiKey类是包含API密钥本身的模型,它保存在所有supported Auth Repositories中。

  1. 我是否需要实现类似上面的TryAuthenticate方法来验证我的API密钥?

这篇关于使用API密钥验证服务器到服务器的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆