API REST 的 symfony 5 自定义身份验证

Posted

技术标签:

【中文标题】API REST 的 symfony 5 自定义身份验证【英文标题】:symfony 5 custom authentication for API REST 【发布时间】:2021-08-02 17:01:35 【问题描述】:

我正在使用 Symfony 5 开发一个项目。 我创建了用户实体,在 security.yaml 上创建了身份验证流程,一切正常:如果用户想要访问受保护的区域,则会显示登录页面并且身份验证过程有效!太好了!

现在,我想使用 FOSRest Bundle 构建一个 API REST。 我创建了一个特定的控制器来公开一些路由:

/**
 * @Rest\Route("/api")
 *
 */

class APICustomController extends AbstractController

    ...
    /**
    * @Rest\Get("/shoes")
    * @param Request $request
    * @Method("GET")
    *
    * @return JsonResponse
    */
    public function getShoes(Request $request)

        ....
        return JsonResponse::fromJsonString(array('msg' => 'OK'));

    


这里是我的 security.yaml

security:
    enable_authenticator_manager: true
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_VIEWER: ROLE_USER

    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
        api_user_provider:
            entity:
                class: App\Entity\User
                property: api_token
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\DealmapLoginAuthenticator
            logout:
                path: app_logout

        api:
            stateless: true
            lazy: true
            guard:
                authenticators:
                    - App\Security\TokenAuthenticator
            pattern: ^/api/
            provider: api_user_provider

    access_control:
        -  path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/api, role: IS_AUTHENTICATED_FULLY 

我按照这里给出的步骤操作:https://symfony.com/doc/current/security/guard_authentication.html

问题出在下面的调用

curl -X GET \
  http://www.example.com/api/shoes \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'x-auth-token: test'

它受到 ma​​in 防火墙的保护(因此它会返回登录页面),而不是像预期的那样受到 api 的保护。我希望收到 json 格式的错误消息。

怎么了??

提前致谢

【问题讨论】:

【参考方案1】:

好的,我找到了解决办法!

我把它贴在这里以防将来有人需要它。

配置都是正确的,但是路径/api/shoes之所以被主防火墙管理,是因为规则的执行顺序。

防火墙 ma​​in 处理所有规则,而 api 仅处理具有 ^/api 模式的规则,所以最严格的规则应该放在security.yaml中的防火墙定义中,如下所示:

security:
    enable_authenticator_manager: true
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_VIEWER: ROLE_USER

    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
        api_user_provider:
            entity:
                class: App\Entity\User
                property: api_token
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api:
            stateless: true
            lazy: true
            guard:
                authenticators:
                    - App\Security\TokenAuthenticator
            pattern: ^/api/
            provider: api_user_provider
        main:
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\DealmapLoginAuthenticator
            logout:
                path: app_logout

    access_control:
        -  path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/api, role: IS_AUTHENTICATED_FULLY 

【讨论】:

以上是关于API REST 的 symfony 5 自定义身份验证的主要内容,如果未能解决你的问题,请参考以下文章

VueJs 前端的无效 CSRF 令牌错误(symfony 5)

Laravel 5 - 在 Rest API 服务器上自定义 JSON 响应

Symfony4 REST API (LexikJWTAuthenticationBundle) 的并发请求

实现REST API Symfony 3

Symfony2 Form + AngularJS for REST API = 表单验证额外字段错误

Symfony2 通过第 3 方 REST API 进行身份验证