认证插件
什么是身份验证插件?
它是一种插件,允许管理谁可以访问或发布到特定的软件包。 默认情况下,内置了htpasswd
,但可以轻松地被你自己替换。
开始
认证插件在 auth:
部分中定义,如下所示:
auth:
htpasswd:
file: ./htpasswd
还可以将多个插件串联起来:
auth:
htpasswd:
file: ./htpasswd
anotherAuth:
foo: bar
bar: foo
lastPlugin:
foo: bar
bar: foo
如果链中的一个插件能够处理请求,那么接下来的插件将被忽略。
认证插件是如何工作的?
基本上我们需要返回一个带有一个名为 authenticate
的方法的对象,该方法将接收3个参数(user, password, callback
)。
在每次请求上,authenticate
将被触发,插件应返回凭据,如果 authenticate
失败,它将默认回退到 $anonymous
角色。
API
interface IPluginAuth<T> extends IPlugin<T> {
authenticate(user: string, password: string, cb: AuthCallback): void;
adduser?(user: string, password: string, cb: AuthCallback): void;
changePassword?(user: string, password: string, newPassword: string, cb: AuthCallback): void;
allow_publish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
allow_access?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
allow_unpublish?(
user: RemoteUser,
pkg: AllowAccess & PackageAccess,
cb: AuthAccessCallback
): void;
apiJWTmiddleware?(helpers: any): Function;
}
只有
adduser
,allow_access
,apiJWTmiddleware
,allow_publish
和allow_unpublish
是可选的,verdaccio 在所有这些情况下提供了备用方案。
apiJWTmiddleware
方法
自 v4.0.0
起
apiJWTmiddleware
是在 PR#1227 上引入的,以便完全控制令牌处理程序,重写此方法将禁用 login/adduser
支持。 我们建议除非完全必要,否则不要实现此方法。 请参阅此处的完整示例。
我应该在每个方法中返回什么?
在撰写本文时,Verdaccio 依靠的是 callback
函数。 每个方法都应调用方法,返回的内容很重要,让我们回顾一下如何做到这一点。
authentication
回调
身份验证执行完毕后,有两个选项可以向 verdaccio
提供响应。
如果认证失败
如果验证不成功,则返回 false
作为第二个参数。
callback(null, false);
如果认证成功
授权成功。
groups
是用户所属组的字符串数组。
callback(null, groups);
如果身份验证产生错误
身份验证服务可能会失败,您可能希望在用户响应中反映这一点,例如:服务不可用。
import { getInternalError } from '@verdaccio/commons-api';
callback(getInternalError('something bad message), null);
登录失败与服务错误不同,如果要通知用户凭据有误,只需返回
false
而不是 groups 列表。 该行为主要取决于您。
adduser
回调
如果添加用户成功
如果服务能够创建用户,则返回 true
作为第二个参数。
callback(null, true);
如果添加用户失败
除成功之外的任何其他操作都必须返回错误。
import { getConflict } from '@verdaccio/commons-api';
const err = getConflict('maximum amount of users reached');
callback(err);
changePassword
回调
如果请求成功
如果服务能够创建用户,则返回 true
作为第二个参数。
const user = serviceUpdatePassword(user, password, newPassword);
callback(null, user);
如果请求失败
除成功之外的任何其他操作都必须返回错误。
import { getNotFound } from '@verdaccio/commons-api';
const err = getNotFound('user not found');
callback(err);
allow_access
、allow_publish
或 allow_unpublish
回调
这些方法旨在允许或拒绝触发某些操作。
如果请求成功
如果服务能够创建用户,则返回 true
作为第二个参数。
allow_access(user: RemoteUser, pkg: PackageAccess, cb: Callback): void {
const isAllowed: boolean = checkAction(user, pkg);
callback(null, isAllowed)
}
如果请求失败
除成功之外的任何其他操作都必须返回错误。
import { getNotFound } from '@verdaccio/commons-api';
const err = getForbidden('not allowed to access package');
callback(err);
生成身份验证插件
有关详细信息,请查看我们的插件生成器页面。 在终端上运行yo
命令,按照步骤操作。
➜ yo verdaccio-plugin
Just found a `.yo-rc.json` in a parent directory.
Setting the project root at: /Users/user/verdaccio_yo_generator
_-----_ ╭──────────────────────────╮
| | │ Welcome to │
|--(o)--| │ generator-verdaccio-plug │
`---------´ │ in plugin generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What is the name of your plugin? service-name
? Select Language typescript
? What kind of plugin you want to create? auth
? Please, describe your plugin awesome auth plugin
? GitHub username or organization myusername
? Author's Name Juan Picado
? Author's Email jotadeveloper@gmail.com
? Key your keywords (comma to split) verdaccio,plugin,auth,awesome,verdaccio-plugin
create verdaccio-plugin-authservice-name/package.json
create verdaccio-plugin-authservice-name/.gitignore
create verdaccio-plugin-authservice-name/.npmignore
create verdaccio-plugin-authservice-name/jest.config.js
create verdaccio-plugin-authservice-name/.babelrc
create verdaccio-plugin-authservice-name/.travis.yml
create verdaccio-plugin-authservice-name/README.md
create verdaccio-plugin-authservice-name/.eslintrc
create verdaccio-plugin-authservice-name/.eslintignore
create verdaccio-plugin-authservice-name/src/index.ts
create verdaccio-plugin-authservice-name/index.ts
create verdaccio-plugin-authservice-name/tsconfig.json
create verdaccio-plugin-authservice-name/types/index.ts
create verdaccio-plugin-authservice-name/.editorconfig
I'm all done. 运行npm install来安装所需的依赖项。 如果失败,尝试自己运行该命令。
⸨ ░░░░░░░░░░░░░░░░░⸩ ⠋ fetchMetadata: sill pacote range manifest for @babel/plugin-syntax-jsx@^7.7.4 fetc
待安装完成,就可以访问你的项目了。
➜ cd verdaccio-plugin-service-name
➜ cat package.json
{
"name": "verdaccio-plugin-service-name",
"version": "0.0.1",
"description": "awesome auth plugin",
...
完整实现 ES5 示例
function Auth(config, stuff) {
var self = Object.create(Auth.prototype);
self._users = {};
// config for this module
self._config = config;
// verdaccio logger
self._logger = stuff.logger;
// pass verdaccio logger to ldapauth
self._config.client_options.log = stuff.logger;
return self;
}
Auth.prototype.authenticate = function (user, password, callback) {
var LdapClient = new LdapAuth(self._config.client_options);
....
LdapClient.authenticate(user, password, function (err, ldapUser) {
...
var groups;
...
callback(null, groups);
});
};
module.exports = Auth;
配置将如下所示:
auth:
htpasswd:
file: ./htpasswd
其中htpasswd
是插件名称的后缀。 例如:verdaccio-htpasswd
,正文的其余部分将是插件配置参数。
社区身份验证插件列表
- verdaccio-bitbucket:verdaccio 的 Bitbucket 身份验证插件。
- verdaccio-bitbucket-server:verdaccio 的Bitbucket 服务器身份验证插件。
- verdaccio-ldap:verdaccio 的 LDAP 身份验证插件。
- verdaccio-active-directory:verdaccio 的 Active Directory 身份验证插件
- verdaccio-gitlab:使用 GitLab 个人访问令牌进行身份验证
- verdaccio-gitlab-ci:启用 GitLab CI 对 verdaccio 进行身份验证。
- verdaccio-htpasswd: 基于 htpasswd 文件的认证插件(内置),用于 verdaccio
- verdaccio-github-oauth: 用于 verdaccio 的 Github oauth 验证插件。
- verdaccio-github-oauth-ui:verdaccio 登录按钮的 GitHub OAuth 插件。
- verdaccio-groupnames:利用
$group
语法处理动态组关联的插件。 与 ldap 插件配合使用效果最佳。 - verdaccio-sqlite:Verdaccio 的 SQLite 身份验证插件
- verdaccio-okta-auth Verdaccio Okta Auth
- verdaccio-azure-ad-login 让用户通过 Azure AD OAuth 2.0 API 验证进入 Verdaccio
- verdaccio-auth-gitlab使用 gitlab 个人访问令牌的 Verdaccio 身份验证插件。
你开发了新插件吗? 在此添加 !