Symfony 使用FOSUserBundle+;FOSOAuthServerBundle

Symfony 使用FOSUserBundle+;FOSOAuthServerBundle,symfony,oauth-2.0,fosuserbundle,fosrestbundle,fosoauthserverbundle,Symfony,Oauth 2.0,Fosuserbundle,Fosrestbundle,Fosoauthserverbundle,我一直在努力设置FOSUserBundle/RestBundle/OAuthServerBundle三人组,以创建一个无头后端,然后我可以将一个单独的前端放在上面,并最终扩展到移动和可能的第三方API访问。我有基于各种可用资源和指令的常规配置,可以使用客户端凭据生成访问令牌 要添加到的应用程序是一个现有的应用程序,它使用标准Symfony/Twig进行前端/后端交互,并使用FOSUserBundle进行身份验证 我有两个与身份验证流程相关的问题 我希望用户能够访问API的某些部分,而无需通过客户

我一直在努力设置FOSUserBundle/RestBundle/OAuthServerBundle三人组,以创建一个无头后端,然后我可以将一个单独的前端放在上面,并最终扩展到移动和可能的第三方API访问。我有基于各种可用资源和指令的常规配置,可以使用客户端凭据生成访问令牌

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

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

  • 我希望用户能够访问API的某些部分,而无需通过客户端级别的身份验证,有些部分将需要用户级别的身份验证来验证它们是否拥有请求的资源。我没有找到一个方法来做到这一点。我发现一些帖子在谈论可能性,但没有给出如何实现的任何方向。我相信我需要在控制器级别检查是否有适当的访问权限,可能需要使用自定义投票者,因为在与客户端进行身份验证后,检查“是否已完全验证”将返回为true。我希望能够通过编程方式验证用户,绕过UI登录表单-这可能只是覆盖了FOSUserBundle登录控制器,但我不确定
  • 我需要创建一个没有访问令牌过期的客户端,或者找到一种实现刷新令牌的方法。我真的不明白为什么我自己的应用程序需要刷新令牌,但如果这是标准的方式,我同意下面的规范
  • 下面是一些相关的代码,尽管大体上这些代码是从FOSOAuthServer安装指南复制过来的标准代码

    security.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 }
    
    广告1) 我用
    security.yml
    中的两个防火墙解决了您的问题。 由于Symfony在
    security.yml中寻找第一个匹配项,我设置了第一个防火墙,允许匿名用户进入:

    api_anonym_area:
        pattern: (^/api/forgotten-password/.*)
        stateless:  true
        fos_oauth:  true
        anonymous: true
    
    我用正则表达式捕捉URL并给出
    匿名:true

    作为第二道防火墙,我有一个正则表达式,它可以捕获所有

    api_auth_area:
        pattern:    ^/
        fos_oauth:  true
        stateless:  true
        anonymous:  false
    
    因此,在您的情况下,如果您希望匿名用户访问/rest/doc,请将放在防火墙前面:rest
    如下所示:

    rest_doc:
        pattern: ^/rest/doc
        fos_oauth: true
        stateless: true
        anonymous: true
    
    广告2) 具有无限访问令牌生存期不是一种好的做法,但您可以在
    config.yml
    中将大整数设置为
    access\u token\u life

    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
    

    在更改/添加访问权限/刷新令牌\u生命周期后,需要根据您的环境运行“php应用程序/控制台缓存:清除--env=prod/dev”!