认证与授权

SQL 客户端认证提供程序

我们提供了 AuthenticationProvider 以及 AuthorizationProvider 的实现,它们使用 Vert.x SqlClient 对任何符合 SQL 标准的数据库执行认证和授权。要使用此项目,请将以下依赖项添加到您的构建描述符的 dependencies 部分中

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-auth-sql-client</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-auth-sql-client:5.0.1'

要创建一个实例,您首先需要一个 SqlClient 的实例。要了解如何创建,请查阅 SQL 客户端的文档。

一旦您拥有其中一个实例,就可以按如下方式创建 SqlAuthentication 实例

SqlAuthenticationOptions options = new SqlAuthenticationOptions();
// SQL client can be any of the known implementations
// *. Postgres
// *. MySQL
// *. etc...
AuthenticationProvider authenticationProvider =
  SqlAuthentication.create(sqlClient, options);

一旦您获得了实例,就可以像使用任何 AuthenticationProvider 一样对其进行认证和授权。

开箱即用的配置假定用于认证和授权的某些查询,如果您想将它们与不同的数据库模式一起使用,可以通过 setAuthenticationQuerysetPermissionsQuerysetRolesQuery 操作轻松更改这些查询。

存储的基本数据定义应如下所示

--
-- Take this script with a grain of salt and adapt it to your RDBMS
--
CREATE TABLE users (
  username VARCHAR(255) NOT NULL,
  password VARCHAR(255) NOT NULL
);

CREATE TABLE users_roles (
  username VARCHAR(255) NOT NULL,
  role VARCHAR(255) NOT NULL
);

CREATE TABLE roles_perms (
  role VARCHAR(255) NOT NULL,
  perm VARCHAR(255) NOT NULL
);

ALTER TABLE users ADD CONSTRAINT pk_username PRIMARY KEY (username);
ALTER TABLE users_roles ADD CONSTRAINT pk_users_roles PRIMARY KEY (username, role);
ALTER TABLE roles_perms ADD CONSTRAINT pk_roles_perms PRIMARY KEY (role, perm);

ALTER TABLE users_roles ADD CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users(username);

哈希策略

此提供程序使用 phc sf spec 来哈希密码。

如果您已有正在运行的旧版应用程序,切换策略将导致现有密码失效。新格式不会受到此影响。为了升级,请要求用户重置密码并相应地更新记录。
建议始终将密码作为哈希值存储在数据库表中,并且这些哈希值应该使用盐值(盐值也应存储在同一行中)生成。应使用强大的哈希算法。强烈建议永远不要以明文形式存储密码。

Vert.x Auth SQL 客户端与 GDPR

GDPR 是欧盟通用法律的一项法规。它凌驾于/取代国家数据保护法,并扩展了之前已有的指令。本手册的这一部分绝不是对该法规的全面解读,它只是一个简短的摘要,说明此组件如何符合要求。不遵守要求的公司可能面临其营业额 4% 或 2000 万欧元的罚款。因此,我们希望确保作为 Vert.x Auth SQL 客户端的用户,您正在遵守该法规的正确轨道上。

该法律定义了某些术语

  • 数据主体 - 个人数据被处理的人(例如:用户)

  • 个人数据 - 任何关于可识别或已识别个人的数据

  • 数据处理 - 对个人数据进行的任何操作(手动或自动化)

  • 控制者 - 请求和使用数据的实体(公司)

  • 处理者 - 代表控制者处理数据的任何实体(例如:云服务提供商)

GDPR 定义了以下功能

  • “遗忘我” - 被遗忘权(删除权)

  • 将资料标记为受限 - 限制处理权

  • 导出数据 - 数据可携权

  • 允许资料编辑 - 更正权

  • 查看我的所有数据 - 访问权

  • 同意复选框

  • 年龄检查

  • 数据销毁 - 数据最小化原则

此模块通过不存储任何关于数据主体的可识别信息来遵守 GDPR。唯一的引用是用户名,它不与任何个人数据关联。

为了向您的应用程序添加个人数据,您应该创建自己的数据模式,并使用用户名列作为您数据的外键。一个提示是,您应该有一个布尔标志来将个人数据标记为受限,以符合限制处理权,这意味着如果您需要处理数据,例如:从邮件列表发送批量电子邮件,如果该标志为 true,则不允许这样做。

被遗忘权并不意味着您必须从应用程序中删除所有记录,例如:在银行中,此权利不能用于抹去正在进行的贷款或债务。您可以保留应用程序数据,但必须删除个人数据。在 Vert.x Auth SQL 的情况下,您应该删除您的表,但只要无法将用户名与个人数据关联起来,您仍然可以使用指向用户名的外键。

重要提示是,这必须在备份中保留!一个提示是,将数据备份和数据擦除操作放在不同的存档中,以便它们可以单独重放。

密码哈希

与任何应用程序一样,有时您需要将新用户存储到数据库中。您可能知道,密码并非以明文形式存储,而是根据哈希策略进行哈希。在将新密码存储到数据库之前,需要使用相同的策略对其进行哈希处理。这是一项分 3 步完成的任务。

  1. 生成盐字符串

  2. 根据盐字符串哈希密码

  3. 将其存储到数据库

String hash = sqlAuth.hash(
  "pbkdf2", // hashing algorithm (OWASP recommended)
  VertxContextPRNG.current().nextString(32), // secure random salt
  "sausages" // password
);

// save to the database
sqlClient
  .preparedQuery("INSERT INTO users (username, password) VALUES ($1, $2)")
  .execute(Tuple.of("tim", hash))
  .onSuccess(rowset -> {
    // password updated
  });

认证

使用此实现进行认证时,它假定认证信息中存在 usernamepassword 字段

Credentials authInfo = new UsernamePasswordCredentials(
  "tim", "sausages");

authProvider.authenticate(authInfo)
  .onSuccess(user -> System.out.println("User: " + user.principal()))
  .onFailure(err -> {
    // Failed!
  });

授权 - 权限-角色模型

尽管 Vert.x 认证本身不强制要求任何特定的权限模型(它们只是不透明的字符串),但此实现假定了一个熟悉的用户/角色/权限模型,其中一个用户可以拥有零个或多个角色,一个角色可以拥有零个或多个权限。

如果要验证用户是否具有特定权限,只需按如下方式将用户与给定权限进行匹配

sqlAuthZ.getAuthorizations(user)
  .onSuccess(v -> {
    if (PermissionBasedAuthorization.create("commit_code").match(user)) {
      // Has permission!
    }
  });