glance-project / keycloak-middleware
Keycloak 中间件
Requires
- php: ^8.2
- glance-project/cern-authentication: ^1.0
- glance-project/error-middleware: ^1.0.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- dq5studios/psalm-junit: ^2.0
- phpunit/phpunit: ^8.5
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.1
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 异常。对于 localhost 和 127.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."
}
]
}