zim32/cert-auth-bundle

双因素x509证书认证

1.2.0 2015-11-09 16:55 UTC

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"

就是这样。