zim32 / cert-auth-bundle
双因素x509证书认证
Requires
- php: >=5.4.0
- ext-openssl: *
- lib-openssl: *
- symfony/symfony: ~2.7
This package is auto-updated.
Last update: 2024-09-06 01:58:01 UTC
README
将双因素证书认证集成到您的项目中。
使用此包,您可以轻松地将基于x509的双因素浏览器认证集成到您的项目中。
基本功能
- 紧密集成到Symfony2防火墙系统中(更少的代码,更安全)
- 集成到任何认证方法之上 - http基本认证、表单登录、预认证等...
- 自动生成、存储和恢复x509证书
- 基于持久化器、过滤器和管理器的可插拔证书存储系统(以您喜欢的任何方式存储您的证书)
- 灵活的访问规则:将IP、电子邮件或任何自定义字段存储到客户端证书中,然后通过Symfony表达式语言进行筛选
- 为您的客户提供卓越的安全性:黑客必须存储用户证书,知道其凭证,即使在这种情况下,如果您通过证书中存储的IP拒绝访问,几乎也不可能登录
- 由于x509 ValidFrom和ValidTo字段由nginx或类似服务器自动验证,因此可以自动减少无效账户给您带来麻烦的可能性
它是如何工作的?
- 用户按常规登录
- 用户被重定向到拒绝页面
- 用户输入他的安全词并生成证书
- 生成的证书存储在服务器上(本地文件系统、数据库、{您自定义的存储)
- 用户下载证书并将其安装到浏览器中
- 用户刷新页面并进入管理界面
- 您的前端服务器堆栈验证用户证书并将几个SERVER变量传递到后端
- 包检查这些变量以授予或拒绝访问
如果用户去另一台电脑怎么办?
- 用户按常规登录
- 系统检测到他本地有证书
- 用户被重定向到恢复页面
- 用户输入他的安全词并重新下载证书
证书受密码保护,即使是您的管理员也无法查看其内容。
内容
安装
配置参考
自定义
禁用自动证书恢复
运行测试
使用命令行
如何添加自定义字段
安装
通过composer下载
composer require zim32/cert-auth-bundle
将包添加到您的Kernel
# app/AppKernel.php $bundles = array( ... new Zim\CertAuthBundle\ZimCertAuthBundle(), ... );
导入路由
# app/config/routing.yml zim_cert_auth: resource: "@ZimCertAuthBundle/Resources/config/routing.yml" prefix: /cert
生成CA证书(如果您没有的话)
mkdir /{your_app_root}/cert cd /{your_app_root}/cert openssl genrsa -des3 -out private.pem 4096 openssl req -new -x509 -key private.pem -out CA.crt -days 365 chmod a-rwx * && chmod u+r *
修改nginx配置。在服务器部分添加行
# /etc/nginx/sites-available/yoursite.conf
server {
...
ssl_verify_client optional;
ssl_trusted_certificate /{your_app_root}/cert/CA.crt;
...
}
根据nginx的版本,您应该添加 ssl_client_certificate /{your_app_root}/cert/CA.crt; 而不是 ssl_trusted_certificate,但这不是推荐选项,考虑更新您的nginx服务器。
修改您的openssl配置文件
此包使用自定义openssl扩展部分称为 zim_usr_cert 来防止与现有配置的不同冲突。因此,请将其添加到openssl配置文件的末尾(在Debian /etc/ssl/openssl.cnf)
[zim_usr_cert]
basicConstraints=critical,CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
用于PHP-FPM
fastcgi_param CLIENT_CERT $ssl_client_raw_cert;
fastcgi_param CLIENT_CERT_OK $ssl_client_verify;
用于代理转发
proxy_set_header CLIENT_CERT $ssl_client_raw_cert;
proxy_set_header CLIENT_CERT_OK $ssl_client_verify;
添加存储生成的客户端证书的目录
mkdir /{your_app_root}/cert/clients
添加包配置
# app/config/config.yml ... zim_cert_auth: ca_path: %kernel.root_dir%/cert/CA.crt ca_key_path: %kernel.root_dir%/cert/private.pem ca_key_password: my_des3_password client_csr_options: countryName: UA organizationName: YOUR ORGANIZATION NAME Limited cert_content_server_var: CLIENT_CERT cert_storage_formatter: id: zim_cert_auth.certificate_storage.formatter.pkcs12 options: [] cert_storage_persister: id: zim_cert_auth.certificate_storage.persister.localfs options: rootDir: %kernel.root_dir%/cert/clients
修改安全配置
# app/config/security.yml firewalls: firewallname: ... pattern: ^/admin access_denied_handler: zim_cert_auth.access_denied_handler zim_cert: ~ ... access_control: ... - { path: ^/cert/denied, role: IS_AUTHENTICATED_FULLY } - { path: ^/admin, allow_if: "'ROLE_ADMIN' in roles and 'ROLE_CERT_AUTHENTICATED_FULLY' in roles" }
配置参考
参见 文档
自定义
此包有四个模板
- Resources/views/Denied/layout.html.twig
- Resources/views/Denied/index.html.twig
- Resources/views/Denied/restore.html.twig
- Resources/views/Denied/blocked.html.twig
使用 Symfony 覆盖模板 技巧来覆盖它们,例如添加如何将证书安装到浏览器中的说明。
如果需要一些自定义逻辑,请覆盖 Controller/AccessDeniedController。
将持久化器更改为以其他方式存储客户端证书,例如在数据库中而不是使用 localfs。
禁用自动证书恢复
如果您想禁用证书自动恢复,只需将以下内容添加到 config.yml 文件中
zim_cert_auth: ... disable_cert_restore: true
运行测试
cd /{your_project_root} && KERNEL_DIR=./app ./bin/phpunit vendor/zim32/cert-auth-bundle/Tests/
使用命令行
您可以使用以下命令导出客户端证书和私钥
app/console zim:cert:dump -p {secure_word} {identity}
您可以从存储中删除证书
app/console zim:cert:remove {identity}
如何添加自定义字段
假设您想将 ipAddress 字段添加到您的客户端证书中,使其等于当前客户端 IP 地址,然后基于此字段拒绝访问。您应该执行以下几个简单步骤
- 在 注册表 中找到免费的 OID 以防止冲突
- 将自定义 OID 添加到您的 openssl 配置文件中
- 添加事件监听器以将 ipAddress 字段添加到客户端证书
- 添加自定义表达式以验证此字段
步骤 #1
例如,您选择您的公司 OID 部分 1.3.6.1.4.1.77777。因此,您的 ipAddress 字段 OID 应该类似于 1.3.6.1.4.1.77777.1 打开您的 openssl 配置文件,找到 [new_oids] 部分,并添加以下行
[new_oids]
...
ipAddress = 1.3.6.1.4.1.77777.1
步骤 #2
添加 zim_cert.modify_csr 事件监听器
app.listener_modify_csr: class: AppBundle\EventListener\ModifyCSREventListener arguments: [@request_stack] tags: - { name: kernel.event_listener, event: zim_cert.modify_csr, method: handle }
步骤 #3
创建事件监听器
<?php namespace AppBundle\EventListener; use Symfony\Component\HttpFoundation\RequestStack; use Zim\CertAuthBundle\Event\ModifyClientCSREvent; class ModifyCSREventListener { protected $requestStack; public function __construct(RequestStack $requestStack) { $this->requestStack = $requestStack; } public function handle(ModifyClientCSREvent $event) { $event->dn['ipAddress'] = $this->requestStack->getCurrentRequest()->getClientIp(); } }
步骤 #4
从现在起,您可以使用 Symfony 表达式语言来基于此字段拒绝访问。修改您的 config.yml
zim_cert_auth: ... cert_validation_expression: cert["subject"]["CN"] == token.getUserName() && cert["subject"]["ipAddress"] == request.getClientIp() && request.server.get("CLIENT_CERT_OK") === "SUCCESS"
就是这样。