在 API Platform 4 项目中,我需要为 swagger 文档提供身份验证安全性。
为此,我遵循了以下流程:API Platform secure swagger
如果我严格遵循代码,结果是:“访问此资源需要完全身份验证。(401)”
如果我进一步打开防火墙+控制访问,我可以查看我的所有文档资源,而无需从此 URL 进行任何授权控制:/api(这不是目标,因为不安全)
授权按钮和流程似乎已显示,但在禁止结果后生成请求,因为请求中没有 JWT 令牌。
如果使用以下方式访问 /api url,我也尝试不显示资源:
#[ApiResource(
security: "is_granted('ROLE_ADMIN')",
)]
但它什么也没做,资源在没有授权控制的情况下再次显示
处理这段代码你能告诉我为什么以及如何生成一个空白的招摇页面,只有一个授权按钮才能在所有资源信息之后进行访问吗?
security.yaml
:
security:
password_hashers:
App\Entity\Users: 'auto'
providers:
users:
entity:
class: App\Entity\Users
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api:
pattern: ^/api/
stateless: true
provider: users
jwt: ~
main:
json_login:
check_path: auth
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
access_control:
- { path: ^/$, roles: PUBLIC_ACCESS }
- { path: ^/docs, roles: PUBLIC_ACCESS }
- { path: ^/auth, roles: PUBLIC_ACCESS }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
api_platform.yaml
api_platform:
swagger:
api_keys:
JWT:
name: Authorization
type: header
routes.yaml:
auth:
path: /auth
methods: ['POST']
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
最终目的是使用 JWT Token 进行安全的 swagger 显示。文档似乎缺少 API 平台 3 和 4 之间引擎的信息或更改。
您遇到的问题可能源于配置未完全集成 Swagger 和 API 平台的安全设置。以下是如何逐步解决这些问题,以实现需要通过 JWT 令牌进行身份验证的安全 Swagger UI:
为了确保 Swagger 本身是安全的,并且在显示资源之前只显示“授权”按钮,您需要调整 security.yaml 和 api_platform.yaml。
security.yaml 调整
security:
password_hashers:
App\Entity\Users: 'auto'
providers:
users:
entity:
class: App\Entity\Users
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api:
pattern: ^/api/
stateless: true
provider: users
jwt: ~
main:
json_login:
check_path: auth
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
docs:
pattern: ^/docs
stateless: true
provider: users
jwt: ~
access_control:
- { path: ^/$, roles: PUBLIC_ACCESS }
- { path: ^/auth, roles: PUBLIC_ACCESS }
- { path: ^/docs, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
更新您的资源定义,以确保对未经授权的访问进行适当的控制。例如:
#[ApiResource(
security: "is_granted('ROLE_ADMIN')",
securityMessage: "Only admins can access this resource."
)]
class YourEntity
{
// ...
}
这可确保资源隐藏在 Swagger UI 中,除非用户具有适当的角色。
更新您的 api_platform.yaml 文件以将 JWT 身份验证方案正确集成到 Swagger 中:
api_platform:
swagger:
api_keys:
JWT:
name: Authorization
type: header
defaults:
pagination_client_items_per_page: true
mapping:
paths: ['%kernel.project_dir%/src/Entity']
exception_to_status:
Symfony\Component\Security\Core\Exception\AccessDeniedException: 403
在 src/OpenApi/OpenApiFactory.php 中,创建自定义 OpenAPI 定义以包含 JWT 授权按钮。
<?php
namespace App\OpenApi;
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\OpenApi\OpenApi;
use ApiPlatform\OpenApi\Model\Components;
use ApiPlatform\OpenApi\Model\SecurityScheme;
final class OpenApiFactory implements OpenApiFactoryInterface
{
private OpenApiFactoryInterface $decorated;
public function __construct(OpenApiFactoryInterface $decorated)
{
$this->decorated = $decorated;
}
public function __invoke(array $context = []): OpenApi
{
$openApi = $this->decorated->__invoke($context);
$components = $openApi->getComponents() ?: new Components();
$components = $components->withSecuritySchemes([
'bearerAuth' => new SecurityScheme(
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
),
]);
$openApi = $openApi->withComponents($components);
$openApi = $openApi->withSecurity([['bearerAuth' => []]]);
return $openApi;
}
}
在config/services.yaml中注册OpenAPI Factory服务:
services:
App\OpenApi\OpenApiFactory:
decorates: 'api_platform.openapi.factory'
所有操作后不要忘记清除缓存。