1

我一直在設置FOSUserBundle/RestBundle/OAuthServerBundle三重奏來創建無頭後端,然後我可以將單獨的前端放在頂端,並最終擴展到移動設備,並且可能的第三方API訪問。基於可用的各種資源和指令,我具有常規配置,並且可以使用客戶端證書生成訪問令牌。使用FOSUserBundle + FOSOAuthServerBundle進行用戶身份驗證流程

這是被添加到應用程序是一個現有的使用標準的Symfony /枝條爲前端/後端相互作用,並使用FOSUserBundle進行認證。

我有相關的認證流程兩個問題。

  1. 我希望用戶能夠訪問的API的某些部分沒有經過認證的客戶端級別,而有些部分需要用戶級身份驗證來驗證自己擁有所請求的資源。我沒有找到辦法做到這一點。我發現帖子在談論這種可能性,但沒有給出如何實現它的任何方向。我相信我需要在控制器級別檢查適當的訪問權限,可能使用自定義選民,因爲在與客戶端進行身份驗證之後,檢查「IS_AUTHENTICATED_FULLY」是否會恢復爲真。我希望能夠以編程方式驗證用戶,繞過UI登錄表單 - 這可能只是重寫FOSUserBundle登錄控制器,但我不確定。
  2. 我要麼需要在不訪問令牌到期創建一個客戶端或找到一種方法來實現刷新令牌。我真的不明白爲什麼我自己的應用程序需要刷新令牌,但如果這是做標準的方式,我可以遵循以下規範。

下面是一些相關的代碼,儘管總的來說代碼是從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

公元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索姆前ething這樣的:

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

公元2) 它不是很好的做法,有無限的訪問令牌生存,但是你可以通過大整數設置爲access_token_lifetime做在config.yml

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 ou t的盒子