glance-project/keycloak-middleware

Keycloak 中间件

v1.0.0 2024-05-15 15:39 UTC

This package is auto-updated.

Last update: 2024-09-01 08:43:48 UTC


README

CERN Keycloak 认证的 PSR-15 中间件。

安装

使用 Composer 安装

composer require glance-project/keycloak-middleware

如果使用 Apache,请将以下内容添加到 .htaccess 文件中。否则,PHP 将无法访问 Authorization: Bearer 标头。

RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

入门

要使用此库,您需要在应用门户上注册一个应用程序。如果您不知道这是什么意思,请参阅CERN 授权服务文档

应用程序注册后,您将需要 客户端 ID客户端密钥

用法

此中间件可以与任何兼容 PSR-7 和 PSR-15 的框架一起使用。以下示例将使用 Slim。

中间件创建有两个必需参数:客户端 ID客户端密钥

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;

$app = new \Slim\App();

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET")
);

$app->add($keycloakMiddleware);

认证后,用户将被注入到请求中。您可以通过 keycloak-user 属性访问它。

$user = $request->getAttribute("keycloak-user");
$personId = $user->personId();
$body = "User Person ID: {$personId}";

$response->getBody()->write($body);

路径

可选的 paths 参数允许您指定 API 的受保护部分。您不需要指定每个 URL。相反,将路径设置视为文件夹。在以下示例中,所有以 /api/private 开头的路径都将进行认证。如果不定义 paths,则所有路由都将受到保护。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;

$app = new \Slim\App();

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET"),
    ["/api/private"]
);

$app->add($keycloakMiddleware);

透传

使用可选的 passThrough 参数,您可以针对 paths 参数进行例外处理。在以下示例中,所有以 /api 开头的路径都将进行认证,但 /api/public 除外,它将不会进行认证。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;

$app = new \Slim\App();

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET"),
    ["/api"],
    ["/api/public"]
);

$app->add($keycloakMiddleware);

Keycloak 提供程序

您可以选择通过 create() 方法提供自己的 Glance\CernAuthentication\KeycloakProvider 实例。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;

$app = new \Slim\App();

$keycloakProvider = KeycloakProvider(/* ... */);

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET"),
    ["/api"],
    [],
    $keycloakProvider
);

$app->add($keycloakMiddleware);

认证后

您可以选择提供一个在用户认证后调用的函数。这对于在中间件外部获取用户信息很有用。

<?php

use Glance\CernAuthentication\User;
use Glance\KeycloakMiddleware\KeycloakMiddleware;
use Psr\Http\Message\ServerRequestInterface;

$app = new \Slim\App();

$keycloakProvider = KeycloakProvider(/* ... */);

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET"),
    ["/api"],
    [],
    $keycloakProvider
    function (ServerRequestInterface $request, User $user) {
        echo $user->personId();
    }
);

$app->add($keycloakMiddleware);

安全

访问令牌本质上就是密码。您应该将其视为密码,并且始终使用 HTTPS。如果中间件检测到通过 HTTP 的不安全使用,它将抛出 InsecureRequestException 异常。对于 localhost127.0.0.1 上的请求,此规则将放宽。

授权

首先,了解 认证授权 之间的区别很重要。

简单来说,认证是验证用户是谁的过程,而授权是验证他们可以访问什么的过程。

对于认证,请使用此库提供的第二个中间件:RoleAuthorizationMiddleware。它检查用户的角色。角色在应用门户上定义,并可以链接到组。

授权中间件可以添加到特定路由

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;
use Glance\KeycloakMiddleware\RoleAuthorizationMiddleware;

$app = new \Slim\App();

// Add authentication middleware
$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET")
);
$app->add($keycloakMiddleware);

// Define routes and add authorization middleware
$app->get("/members", /* route logic */)
    ->add(RoleAuthorizationMiddleware::mustHaveRole("common-user"));

$app->run();

任何角色

检查用户是否至少拥有定义中的一个角色。它使用 OR 操作符。

<?php

use Glance\KeycloakMiddleware\RoleAuthorizationMiddleware;

$app = new \Slim\App();

// Add authentication middleware here

// To access this route, user must be 'common-user' OR 'visitor'
$app->get("/members", /* route logic */)
    ->add(RoleAuthorizationMiddleware::anyOfRoles([ "common-user", "visitor" ]));

所有角色

检查用户是否拥有所有定义的角色。它使用 AND 操作符。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;
use Glance\KeycloakMiddleware\RoleAuthorizationMiddleware;

$app = new \Slim\App();

// Add authentication middleware here

// To access this route, user must be 'team-leader' AND 'active-user'
$app->get("/members", /* route logic */)
    ->add(RoleAuthorizationMiddleware::allOfRoles([ "team-leader", "active-user" ]));

必须拥有角色

检查用户是否拥有特定角色。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;
use Glance\KeycloakMiddleware\RoleAuthorizationMiddleware;

$app = new \Slim\App();

// Add authentication middleware here

// To access this route, user must be 'admin'
$app->get("/members", /* route logic */)
    ->add(RoleAuthorizationMiddleware::allOfRoles("admin"));

异常

如果您将此库与Glance 错误处理中间件结合使用,验证错误将自动转换为适当的 HTTP 响应。

<?php

use Glance\KeycloakMiddleware\KeycloakMiddleware;

$app = new \Slim\App();

$ErrorMiddleware = new \Glance\ErrorMiddleware\ErrorMiddleware(/* ... */);

$keycloakMiddleware = KeycloakMiddleware::create(
    getenv("CLIENT_ID"),
    getenv("CLIENT_SECRET")
);

$app->add($keycloakMiddleware);
$app->add($ErrorMiddleware);

上一个设置中错误响应的示例

{
    "errors": [
        {
            "status": 401,
            "title": "Invalid authentication token.",
            "detail": "Authentication token introspection failed."
        }
    ]
}