4

我需要为一家公司创建一个应用程序,他们希望人们登录到该应用程序以获得不同的权限来执行不同的任务。

我最初的想法是创建一个 MySQL 数据库,将凭据硬编码到应用程序中,然后让应用程序连接到 MySQL 数据库。MySQL 数据库将有一个名为“users”的表,该表将存储用户名、密码和权限。然后应用程序将查询服务器并执行身份验证。

最大的问题是将 MySQL 凭据硬编码到应用程序中。如果应用程序落入坏人之手,如果他们四处寻找凭据并开始删除表,他们可能会对 MySQL 数据库造成很大损害。

所以我想开发一个服务器来充当 MySQL 数据库的接口。例如,客户端应用程序将通过 TCP 连接到服务器,服务器连接到 MySQL 数据库。这样,MySQL 凭据就不会暴露给最终用户。但是,这意味着我必须开发一个服务器应用程序,它 a) 将更难为我的客户维护和部署(而不是仅仅设置 MySQL 服务器)和 b) 有可能引入更多错误,因为我有一个额外的系统我需要做(这与部署错误修复等有关)

所以我在想,与其在数据库中有一个用户表并让应用程序使用硬编码的凭据直接连接到 MySQL 服务器,不如为最终用户提供实际的 MySQL 用户凭据,他们将在其中输入应用程序以连接到MySQL 服务器。这意味着如果有人拿到了应用程序,他们不会对 MySQL 数据库造成任何损害,但仍然存在最终用户将其凭据提供给错误人的风险。

让桌面应用程序连接到 MySQL 数据库的最佳方法是什么?除了我想到的3个之外还有其他解决方案吗,或者您对我的解决方案有什么想法?

4

3 回答 3

3

正如@Perception 指出的那样。你最好的选择是在 MySQL 前面实现一个 Web 服务。您不希望来自未知 IP 地址的未知数量的客户端都可以访问您的数据库。

通过绑定 MySQL 连接来 DOS 攻击你真的很容易。更不用说您将非常严重地限制您扩展后端服务以满足不断增长的客户群的需求的能力,而两者之间没有 Web 服务。

Web 服务还可以为您提供以多种方式控制用户身份验证和授权的能力(用户/通行证组合、基于令牌的访问、OAuth 访问等)。

于 2013-03-19T00:37:10.767 回答
2

在我工作的地方,我看到了两种做法:

  1. 每个实体(个人、事物或企业(取决于所需的粒度级别)访问数据库)都有自己的凭据。这用于 MSSQL 和 Rocket Universe 数据库。这主要是零售和遗留软件。

  2. 我们自己托管应用程序并为用户使用单独的身份验证系统。数据库凭据存储在我们托管应用程序的服务器上。客户端对后备数据库一无所知。这些通常是 Web 应用程序和 Web 服务。

我们可以做的事情是我们的许多应用程序实际上通过一个 RESTful 服务进行通信,该服务以某种方式模拟数据库。应用程序本身无权访问数据库。我会阅读关于宁静服务的维基百科文章以获取更多信息。我们的身份验证是使用 Nonce 编码的 HMAC 请求完成的,其中每个用户都获得了与他们的凭据相关联的自己的密钥。

将数据库包装在 Web 服务中会给您带来一些可能的优势:

  • 如果您决定在保留相同信息的同时更改数据库结构,您甚至可能不需要更新客户端应用程序,只需更新服务即可。
  • 凭据永远不会离开服务器,只要没有人可以访问您的服务器,您的凭据就会保持安全。总体上提高了安全性。
  • 如果您的服务足够聪明,您甚至可以将通常在客户端的大部分内部逻辑转移到服务器上,从而使更新和错误修复几乎无缝地传递给客户端。

我看到的缺点:

  • 维护是另一回事
  • 您的应用程序容易受到拒绝服务攻击,但由于它是一个数据库,因此无论如何都可能存在问题
  • 如果服务器宕机,所有客户端应用程序都会宕机,但无论如何,这仍然是个问题。

RESTful 架构:http ://en.wikipedia.org/wiki/Representational_state_transfer

HMAC:http ://en.wikipedia.org/wiki/Hash-based_message_authentication_code

我们的 HMAC 系统是这样工作的:

  • 用户使用用户名和密码登录到他们的本地应用程序。
  • 本地应用程序与我们的身份验证服务进行通信,并获取该用户名和密码的“会话密钥”和共享密钥。
  • 使用会话密钥(在短时间内到期),应用程序创建一个 API 密钥(持续很长时间)并将其存储到计算机。如果用户每次都需要登录,可以使用会话密钥代替 API 密钥。我们这样做主要是为了方便一些程序。如果计算机不安全,则应仅使用会话密钥,并且本地计算机上不存储任何 API 密钥。每次用户登录时,他们都会获得一个新的会话密钥。
  • 对数据库服务的每个请求都伴随着一个 HMAC 签名的随机数,应用程序根据 API 密钥从授权服务中获取该随机数。获得随机数后,应用程序使用共享密钥对其进行签名。这些签名请求只能使用一次,因为 Web 服务(用户对此一无所知)对请求进行身份验证。一旦通过查看使用该特定 API/会话密钥的共享密钥对随机数进行哈希处理是否会产生相同的摘要,已在服务器端对签名的随机数进行了身份验证,该随机数将被标记为过期并授予请求。

如果不使用 HTTPS,上述内容很容易受到中间人攻击,因此人们经常根据 nonce 和请求的 URL 以及时间戳制作消息,并在此基础上计算 HMAC。然后服务器根据 URL 重新创建消息,检查时间戳是否在某个范围内(+/- 4 分钟或其他内容),然后根据该信息授权用户。

为了进一步细化操作,我们还有一个角色系统,用于检查拥有 Session/API Key 的用户是否已被授予请求他们请求的内容的权限。如果他们具有适当的角色,则批准该请求。

简介: 凭据是逐个用户完成的,最终用户不了解数据库,Web 服务将数据库包装在 RESTful API 中,并且使用基于角色的系统来使权限细化。

这只是一个建议,我并不是说这是最好或唯一的方法。这恰好是我们最终在我工作的地方这样做的方式。

于 2013-03-19T00:39:22.680 回答
0

让我们看一下处理数据库的两种方式:

  • 客户端直接连接数据库,操作数据库
  • 服务器连接数据库并提供接口供客户端使用

考虑到您的用例:

有效的有效序列号或存储/读取有关特定用户的信息

它可以通过以下方式设计以提供安全性。(我不是这方面的专家)

  • 客户端直接连接数据库,操作数据库
    • 您不必使用管理员访问数据库,而是仅为客户端创建一个用户,并将用户的访问权限限制为仅查看(某些数据)。您可以通过更改此用户的权限来在数据库中强制执行安全策略。
    • 你可以参考MySQL :: MySQL 5.1 Reference Manual :: 6 Security获取更多信息。
      • 6.2 MySQL访问权限系统
      • 6.3 MySQL 用户账户管理
  • 服务器连接数据库并提供接口供客户端使用
    • 您可以使用 HTTP 并提供接口给客户端使用。并且只有后端连接到数据库。
    • 类似于 RESTful API,有许多易于使用的框架提供身份验证和授权。

在您的情况下,我认为让客户直接访问数据库并不是一个好主意。所以如果可能的话,第二种选择更好。

另请注意,基于密码的身份验证并不理想。

于 2014-05-17T08:55:05.283 回答