waglpz/webapp-security

Web 应用安全实现

2.1.0 2024-09-02 21:17 UTC

This package is auto-updated.

Last update: 2024-09-02 23:00:26 UTC


README

PHP Checked

通过 Composer 安装

composer require waglpz/webapp-security

在 Docker 容器内使用源代码

在某些目录中克隆项目 git clone https://github.com/waglpz/webapp-security.git

进入目录 webapp-security 并运行: bash ./bin/start.sh 以在 Docker 容器内开始工作。

要停止和清理运行: bash ./bin/clean.sh

从 Docker 容器使用 Composer
  1. 安装供应商依赖项 composer install
  2. 显示 Waglpz Composer 命令: composer list | grep waglpz
    1. 检查源代码活力: composer waglpz:check:normal
    2. 检查源代码样式: waglpz:cs-check
    3. 自动修复源代码样式错误: waglpz:cs-fix

API 的基本认证

如何将用户从 HTTP 请求作为 Gherkin 场景进行认证

Szenario: Basic Authentication
    Given: HTTP Request contains 'PHP_AUTH_USER' and 'PHP_AUTH_PW'
    And: We have an Instance of `\Waglpz\Webapp\Security\Authenticator`
    And: We have dependency Instance of `Waglpz\Webapp\Security\UserAuthDataAdapter` injected in `\Waglpz\Webapp\Security\Authenticator`
    When: Runtime call `\Waglpz\Webapp\Security\Authenticator::authenticate(ServerRequestInterface)`
    And: User found via `\Waglpz\Webapp\Security\UserAuthDataAdapter` 
    Then: `Waglpz\Webapp\Security\Authenticator::authenticate(ServerRequestInterface) returns boolean true

示例 PHP 代码

$users = [
    [
        'username' => 'tester@akme.com',
        'role' => 'ROLE_TESTER',
        'password' => 'xxxxxx123',
    ],
];
$authDataAdapter = new \Waglpz\Webapp\Security\CredentialDataAdapterInMemory($users);
$authenticator = new \Waglpz\Webapp\Security\AuthenticatorBasic($authDataAdapter);

/*
 * $request contains valid user "tester@akme.com" and password "xxxxxx123"
 */
$request;
\assert($request instanceof \Psr\Http\Message\ServerRequestInterface);

$authResult = $authenticator->authenticate($request);

\assert($authResult);
\assert($authenticator->username() === 'tester@akme.com');

查找现有用户角色

如何将用户角色作为 Gherkin 场景进行查找

Szenario: Find User Role
    Given: We have an Instance of `\Waglpz\Webapp\Security\UserAuthRolesProvider`
    And: We have dependency Instance of `Waglpz\Webapp\Security\UserAuthDataAdapter` injected in `\Waglpz\Webapp\Security\UserAuthRolesProvider`
    When: Runtime call `\Waglpz\Webapp\Security\UserAuthRolesProvider::findRole(?string)`
    And: User found via `Waglpz\Webapp\Security\UserAuthDataAdapter` 
    Then: `\Waglpz\Webapp\Security\UserAuthRolesProvider::findRole(?string) returns array of Roles

示例 PHP 代码

$users = [
    [
        'username' => 'tester@akme.com',
        'role' => 'ROLE_TESTER',
        'password' => 'xxxxxx123',
    ],
];
$authDataAdapter = new \Waglpz\Webapp\Security\CredentialDataAdapterInMemory($users);
$rolesFinder = new \Waglpz\Webapp\Security\UserAuthRolesProvider($authDataAdapter);

$roles = $rolesFinder->findRole('tester@akme.com');

\assert($roles === ['ROLE_TESTER'])

路由防火墙

如何通过用户角色进行路由安全作为 Gherkin 场景

Szenario: Secure the Route by Firewall
    Given: We have an Instance of `\Waglpz\Webapp\Security\Firewall`
    And: We have a array of Firewall Rules injected in `\Waglpz\Webapp\Security\Firewall`
    When: Runtime call `\Waglpz\Webapp\Security\Firewall::checkRules(ServerRequestInterface, roles)`
    And: User roles matches Firewall Rules  
    Then: No Forbidden 403 Exception was thrown.

示例 PHP 代码

$rules = [
    '/abc-route' => ['ROLE_TESTER'],
];
$users = [
    [
        'username' => 'tester@akme.com',
        'role' => 'ROLE_TESTER',
        'password' => 'xxxxxx123',
    ],
];
$authDataAdapter = new \Waglpz\Webapp\Security\CredentialDataAdapterInMemory($users);
$rolesFinder = new \Waglpz\Webapp\Security\UserAuthRolesProvider($authDataAdapter);

$roles = $rolesFinder->findRole('tester@akme.com');

\assert($roles === ['ROLE_TESTER'])

$firewall = new \Waglpz\Webapp\Security\Firewall($rules);

$request;
\assert($request instanceof \Psr\Http\Message\ServerRequestInterface);

try {
    $firewall->checkRules($request,$currentRoles);
} catch (\Waglpz\Webapp\Security\Forbidden $exception) {
    // this block will not execute, because user current role was matched for route in rules 
}