Skip to main content
编辑本页

Mongo Auth Provider implementation

Vert.X中提供了一个 AuthProvider 的实现,它可以让你使用 MongoClient 针对MongoDb数据库执行认证和授权。

若要在自己的项目中使用它,则需要在构建描述信息的_dependencies_节点中添加如下信息:

  • Maven (在 pom.xml 文件中):

<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-auth-mongo</artifactId>
 <version>3.6.2</version>
</dependency>
  • Gradle (在 build.gradle 文件中):

compile 'io.vertx:vertx-auth-mongo:3.6.2'

如果要创建一个客户端实例,你首先需要一个 MongoClient 的实例,要知道如何创建这个实例可按照文档中的内容实施。

一旦你创建了一个 MongoClient 实例后,就可以按照下边的代码创建 MongoAuth 实例:

var MongoClient = require("vertx-mongo-js/mongo_client");
var MongoAuth = require("vertx-auth-mongo-js/mongo_auth");
var client = MongoClient.createShared(vertx, mongoClientConfig);
var authProperties = {
};
var authProvider = MongoAuth.create(client, authProperties);

创建好上边的实例过后,你就可以使用任何 AuthProvider 针对MongoDB执行认证和授权功能了。

Vert.X的默认标准配置(Out Of the Box)中包含了"user"集合(Collection),用户名字段使用"username"进行存储和读取。

为了避免在"user"集合中出现重复的用户名,应该在"user"集合中给"username"添加唯一索引(Unique Index),你可以在MongoDB服务器中运行下边的片段来完成此操作:

db.user.createIndex( { username: 1 }, { unique: true } )

MongoDB的特性是先查询username字段中的值是否已经存在,然后会插入一个Document,并不能作为一个原子性操作, 基于这个原因你需要添加上边的唯一索引,使用了这个索引过后你的代码会尝试先插入一行数据,如果出现了重复记录则会失败。

根据你自己的需要,你同样可以使用下边的方法改变MongoDB中使用的默认集合(Collection)和列(Column)名称等信息:

Vert.X默认实现中的密码在数据库中使用了SHA-512算法加密后进行存储,之后会连接对应的`salt`值,这个`salt`值和密码存储在同一个表里。 你可以调用 setSaltField 方法来改变存储`salt`值的字段名称,它的默认值是"salt", 你同样可以使用 setSaltStyle 来改变一些行为。 通过调用 getHashStrategy 方法还可以读取Hash策略设置。

MongoDB中可以设置下边几种`SALT`的值:

NO_SALT :密码就不会执行加密以明文的方式存储。(参考下边WARNING) COLUMN :Vert.X会为每个用户创建一个"salt"值,并且存储在用户表定义的列中;(参考下边WARNING) EXTERNAL :Vert.X仅仅将密码最终加密结果存储在数据库中,"salt"值可以在外部使用,并且可以调用 setExternalSalt 方法进行设置。

如果你想要重写上述行为,则你可以调用 setHashStrategy 方法设置新的Hash策略,并且提供变更过的Hash策略及配置信息。

Warning
强烈建议在设置"salt"值时候使用 EXTERNAL 选项。 NO_SALT 选项仅仅推荐在开发阶段中使用,不仅仅如此, COLUMN 方式也不推荐,因为它会导致 salt 和密码都存储在了同一个地方!
Warning
As of 2018 OWASP recommends the usage of stronger encryption algorithms to hash user passwords for this case you can change from the default (preserved for backwards-compatibility) to PBKDF2. For new projects this should be the standard.
var MongoClient = require("vertx-mongo-js/mongo_client");
var MongoAuth = require("vertx-auth-mongo-js/mongo_auth");
var client = MongoClient.createShared(vertx, mongoClientConfig);
var authProperties = {
};
var authProvider = MongoAuth.create(client, authProperties);
authProvider.setHashAlgorithm('PBKDF2');

Vertx Auth JDBC and GDPR

GDPR is a regulation from the common European Union law. It overrides/supercedes national data protection laws and extents the previously existing directives. This section of the manual is by no means a thorough walkthrough of the regulation, it is just a small summary how this component adheres to the requirements. Companies not adhering to the equirements can be fined on 4% of the turnover or 20 million euro. Therefore we want to make sure that as a user of Vert.x Auth JDBC you’re are on the good track to comply.

The law defines certain terminology:

  • Data Subject - Person whose personal data is processed (e.g.: User)

  • Personal Data - Any data about an identifiable or identified person

  • Data Processing - Any operation (manual or automated) on personal data

  • Controller - The entity (company) that requests and uses the data

  • Processors - Any entity that processes data on behalf of a controller (e.g.: cloud service provider)

GDPR defines the following functionality:

  • "Forget me" - Right to erasure

  • Mark profile as restricted - Right to restriction of processing

  • Export data - Right to portability

  • Allow profile editing - Right to rectification

  • See all my data - Right to access

  • Consent checkboxes

  • Age checks

  • Data destruction - Data minimization principle

This module complies to the GDPR law by not storing any identifiable information about a data subject. The only reference is the username which is not linked to any personal data.

In order to add personal data to your application you should create your own data schema and use the username column as a reference to your data. As a tip you should have a boolean flag to mark the personal data as restricted to comply to the right to restriction of processing which means that if you need to handle the data, e.g.: send a bulk email from a mailing list you are not allowed to do so if the flag is true.

The right to erasure does not mean that you must wipe all records from your application, e.g.: in a bank this right cannot be used to erase a running loan or debt. You are allowed to keep your application data but must erase the personal data. In case of Vert.x Auth JDBC you should delete your table but can still use a reference to the username as long as is not possible to link the username to the personal data.

Important note is that this must survive backups! As a tip backup the data, and data erasure on different archives so they can be replayed individually.

认证

如果认证使用了默认的MongoDB实现,认证信息中用了 usernamepassword 字段:

var authInfo = {
  "username" : "tim",
  "password" : "sausages"
};
authProvider.authenticate(authInfo, function (res, res_err) {
  if (res_err == null) {
    var user = res;
  } else {
    // Failed!
  }
});

如果想要替换上边的 usernamepassword 两个默认字段名,你可以使用 setUsernameCredentialFieldsetPasswordCredentialField 方法。

授权 - Permission/Role模型

尽管Vert.X自身并不要求使用特定的许可模型(它本身只是使用了不透明的字符串),但MongoDB认证中的实现使用了比较熟悉的:用户/角色/许可模型,这样在应用里你可以使用一个或者多个角色,而一个角色也可以拥有一个或者多个许可。

如果要验证一个用户是否拥有特定的许可,则要将许可信息传递到 isAuthorised 中:

user.isAuthorized("commit_code", function (res, res_err) {
  if (res_err == null) {
    var hasPermission = res;
  } else {
    // Failed to
  }
});

如果要验证一个用户是否属于特定角色,则可以使用MongoDB认证前缀(MongoAuth.ROLE_PREFIX)法给角色带上前缀表示:

var MongoAuth = require("vertx-auth-mongo-js/mongo_auth");

user.isAuthorized(MongoAuth.ROLE_PREFIX + "manager", function (res, res_err) {
  if (res_err == null) {
    var hasRole = res;
  } else {
    // Failed to
  }
});