1

我一直在努力设置 FOSUserBundle/RestBundle/OAuthServerBundle 三重奏,以创建一个无头后端,然后我可以在其上放置一个单独的前端,并最终扩展到移动设备和可能的第三方 API 访问。我根据可用的各种资源和说明进行了常规配置,并且可以使用客户端凭据生成访问令牌。

正在添加的应用程序是一个现有的应用程序,它使用标准 Symfony/Twig 进行前端/后端交互并使用 FOSUserBundle 进行身份验证。

我有两个与身份验证流程有关的问题。

  1. 我希望用户能够访问 API 的某些部分而无需通过客户端级别的身份验证,并且某些部分将需要用户级别的身份验证来验证他们拥有所请求的资源。我没有找到一种方法来做到这一点。我发现帖子谈论了这种可能性,但没有给出任何关于如何实现它的方向。我相信我需要在控制器级别检查适当的访问权限,也许使用自定义选民,因为在与客户端进行身份验证后,检查“IS_AUTHENTICATED_FULLY”会返回为真。我希望能够以编程方式对用户进行身份验证,绕过 UI 登录表单——这可能只是覆盖 FOSUserBundle 登录控制器,但我不确定。
  2. 我要么需要创建一个没有访问令牌过期的客户端,要么找到一种方法来实现刷新令牌。我真的不明白为什么我自己的应用程序需要刷新令牌,但如果这是执行此操作的标准方法,我可以遵循以下规范。

下面是一些相关代码,但总的来说,这些代码是从 FOSOAuthServer 设置指南复制过来的漂亮的标准内容。

安全.yml

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls:
        oauth_token:
            pattern:    ^/oauth/v2/token
            security:   false

        rest:
            pattern: ^/rest(?!/doc)
            fos_oauth: true
            stateless: true
            anonymous: false

        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
                success_handler: security.authentication.success_handler
            use_referer: true
            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/rest, roles: [ IS_AUTHENTICATED_FULLY ] }

config.yml 片段

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: AppBundle\Entity\User
    registration:
        form:
            type: AppBundle\Form\Type\RegistrationFormType
    profile:
        form:
            type: user_profile

fos_oauth_server:
    db_driver: orm
    client_class:        AppBundle\Entity\Client
    access_token_class:  AppBundle\Entity\AccessToken
    refresh_token_class: AppBundle\Entity\RefreshToken
    auth_code_class:     AppBundle\Entity\AuthCode
    service:
        user_provider: fos_user.user_provider.username_email
        options:
            supported_scopes: user

fos_rest:
    view:
        view_response_listener: force
        formats:
            json: true
        templating_formats:
            html: true
        mime_types:
            json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
            jpg: ['image/jpeg']
            png: ['image/png']
    body_listener: true
    param_fetcher_listener: true
    allowed_methods_listener: true
    format_listener:
        rules:
            - { path: ^/, priorities: [html, json], fallback_format: json, prefer_extension: false }
4

1 回答 1

1

AD 1)我用两个防火墙 解决了你的问题security.yml。由于 Symfony 正在寻找第一个匹配项,因此security.yml我放置了第一个防火墙以让匿名用户进入:

api_anonym_area:
    pattern: (^/api/forgotten-password/.*)
    stateless:  true
    fos_oauth:  true
    anonymous: true

我用正则表达式捕获 URL 并给出anonymous: true

作为第二个防火墙,我有捕获所有的正则表达式

api_auth_area:
    pattern:    ^/
    fos_oauth:  true
    stateless:  true
    anonymous:  false

因此,在您的情况下,如果您希望匿名用户访问 /rest/doc,请在您的前面 firewall:rest放置如下内容:

rest_doc:
    pattern: ^/rest/doc
    fos_oauth: true
    stateless: true
    anonymous: true

AD 2) 拥有无限的访问令牌生命周期并不是一个好习惯,但您可以config.yml通过将大整数设置为access_token_lifetime

fos_oauth_server:
    service:
        options:
            access_token_lifetime: #number in seconds#

只需使用刷新令牌登录

/oauth/v2/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

它在 FOSOAuthServerBundle 中开箱即用

于 2017-07-10T14:17:47.667 回答