webspot/firewall

此包已被废弃且不再维护。未建议替代包。

支持StackPHP的Webspot防火墙

dev-master 2015-12-27 23:04 UTC

This package is not auto-updated.

Last update: 2023-02-05 20:42:32 UTC


README

Build Status Scrutinizer Code Quality Code Coverage

防火墙是一个StackPHP中间件,可以用来检查某些守卫以防止不想要的请求。通过将防火墙置于您的应用程序和外部世界之间。这是通过将守卫附加到防火墙来完成的,它们响应内部事件并允许或拒绝请求。

实例化防火墙时,您可以选择默认状态是允许还是拒绝。不同的守卫可能会更改当前状态。但是,当更改到允许时,只需继续验证,当更改到拒绝时,这将立即成为最终状态,并且不再检查其他守卫。

事件

所有事件都有伴随的事件对象,它们针对特定需求。

防火墙上有4个主要事件

  • Firewall::EVENT_VALIDATE_REQUEST

主要事件。检查传入的请求是否允许。

  • Firewall::EVENT_REQUEST_ALLOWED

当请求验证完成后允许时,此事件被触发。

  • Firewall::EVENT_REQUEST_REFUSED

当请求验证完成后拒绝时,此事件被触发。

  • Firewall::EVENT_SEND_RESPONSE

允许请求被发送到应用程序后,一旦它返回一个触发此事件的响应,就允许签署响应。

包含的守卫还会触发一些半核心事件

  • Firewall::EVENT_CREATE_TOKEN
  • Firewall::EVENT_VALIDATE_TOKEN
  • Firewall::EVENT_TOKEN_VALIDATED
  • Firewall::EVENT_AUTHENTICATE

守卫

TokenGuard

最早执行,如果存在JSON Web Token (JWT)并且验证所有进一步的守卫,则无需执行。这使得后续请求比初始请求快得多。此配置实例化时也需要最多的配置。

AuthenticationGuard

用于基于HTTP的基本身份验证。接受一个准备好的PDOStatement和一个散列可调用函数来检查HTTP请求头中的用户名和密码。当它验证时,它将反映在EVENT_AUTHENTICATE事件对象上。如果TokenGuard也附加,则将用户ID写入JWT。

IpGuard

允许黑名单和白名单特定的IP地址。黑名单将在其IP在数据库中时拒绝请求。白名单仅在默认状态为拒绝时才有用,在这种情况下,白名单将状态更改为允许。

IpGuard使用一个准备好的PDOStatement实例化,允许它查找IP并返回状态。

UserAgentGuard

类似于IpGuard,但工作在用户代理上。这个不是那么多的安全措施,而是禁止过时的浏览器或特定设备使用您的应用程序的一种方式。

拒绝时

拒绝总是会抛出 FirewallException 异常。建议将 handle() 方法设置为不捕获异常,并在您的前端自行捕获以进行处理。FirewallException 有三种特殊形式:ForbiddenException(应导致 HTTP 状态码 403)、Unauthorized(状态码 401)和 UnsupportedException(默认为 400)。Forbidden 异常在 IpGuard 发现黑名单时抛出,AuthenticationGuard 在遇到被篡改的 JWT 时抛出。UnauthorizedException 在 AuthenticationGuard 没有凭证或凭证认证失败时抛出。UnsupportedException 由 UserAgentGuard 抛出。

关于守卫抛出异常的说明

每当一个守卫抛出异常时,防火墙总是会默认为拒绝并抛出一个通用的 FirewallException 异常,并将实际的异常作为其前一个属性附加。

使用示例

<?php
use Psecio\Jwt;
use Webspot\Firewall\Guard;

// Create a StackPHP compatible application, Silex is used here for the example
$app = new Silex\Application();

// Create the Actual Firewall instance and attach some guards
$firewall = new Webspot\Firewall\Firewall();
$firewall->attachGuard(new Guard\AuthenticationGuard(
    function($username, $password) {
        if ($username === 'test@test.com' && $password === 'password') {
            return 42;
        }
        return null;
    }));
$firewall->attachGuard(new Guard\TokenGuard(
        [],
        new Jwt\Jwt(
            new Jwt\Header('my-very-secret-key'),
            (new Jwt\ClaimsCollection())
                ->add(new Jwt\Claim\Audience($_SERVER['SERVER_NAME']))
                ->add(new Jwt\Claim\Issuer($_SERVER['SERVER_NAME']))
                ->add(new Jwt\Claim\ExpireTime(time() + 7200))
                ->add(new Jwt\Claim\Custom(time() + 3600, Guard\TokenGuard::TOKEN_RENEW_AFTER))
        )
    ));

// Create the StackPHP compatible wrapper for the Firewall
$firewalledApp = new Webspot\Firewall\StackFirewall($app, $firewall);

// Return to normal execution
$request = Symfony\Component\HttpFoundation\Request::createFromGlobals();
$respone = $firewalledApp->handle($request);
$response->send();
$app->terminate($request, $response);