2014/10/20

Symphony2 實作登入驗證功能和權限管理(authentication & authorization )學習筆記(基本的登入管理)

Step 1. 安裝 FOSBundle (Friend of Symphony)

https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md

安裝時可能會遇到問題,參考 http://stackoverflow.com/questions/18913809/trying-to-install-fosuserbundle-but-getting-error

需要先修改 config.yml 內容後才能 composer update

# app/config/config.yml
fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main
    user_class: Acme\UserBundle\Entity\User

Step 2. 閱讀資料

可先閱讀這篇了解大致的機制 [1]
http://symfony.com/doc/current/book/security.html

如果想要快點實際操作可以直接讀這篇 [2]
http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers

我們先從簡單的 Demo Bundle 開始拆解學習

要拆解的程式有
app/config/security.yml
src/Acme/DemoBundle/Resources/routing.yml
src/Acme/DemoBundle/Controller/SecuredController.php

routing.yml 裡頭設定 SecuredController.php 這個資源的 URL 試看 annotation
所以我們可以看到 SecuredController 使用了 Routing Annotation
@Route("/demo/secured")
其中有方法 loginAction(Request $request) 處理 Request

從 security.yml 可以看到有一些安全機制

        demo_secured_area:
            pattern:    ^/demo/secured/
            # it's important to notice that in this case _demo_security_check and _demo_login
            # are route names and that they are specified in the AcmeDemoBundle
            form_login:
                check_path: _demo_security_check
                login_path: _demo_login
            logout:
                path:   _demo_logout
                target: _demo

我們嘗試連到 /demo/secured/ 下的資源,就會被導到 _demo_login 這個路徑,我們可以使用 security.yml 裡設定的帳號密碼進行登入來觀察結果

    providers:
        in_memory:
            memory:
                users:
                    user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                    admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }

可以發現 /demo/secured/hello/admin/world 這個 route 有被設定為 @Security("is_granted('ROLE_ADMIN')")


Step 3. 更換登入驗證方法

根據 [1] 我們可以知道驗證方法大致上有 Login Form, HTTP Authentication, HTTP digest, X.509 Certification 幾種。

可以先註解掉原本的 login 方法後,把登入方法換成 HTTP authentication

firewalls:
        demo_secured_area:
            pattern:    ^/demo/secured/
            anonymous: ~
            http_basic:
                realm: "Secured Demo Area"

結果會發現 /demo/secured/hello/admin/world 會需要登入權限 (由於 Security Annotation)
然而 /demo/secured/hello/world 則不需要。這跟 login 的方式好像有所區別。

Step 4. 抽換 Provider ,使用資料庫的使用者資料

可以先參考 [2] 的內容。首先要先建立 User Entity 並且實作 UserInterface 或是 AdvancedUserInterface

我們先實作簡單的 User 以及 UserRepository ,詳細可以參考 [2],這邊就不貼了。

接下來我們就可以在 security.yml 抽換 Provider

    providers:
        administrator:
            entity: { class: AcmeUserBundle:User, property: username }

還有記得要修改 Encoder

    encoders:
        Acme\UserBundle\Entity\User:
            algorithm: bcrypt

如果想要讓登入的人存取 admin 權限則修改(原為 ROLE_USER)

    public function getRoles()
    {
        return array('ROLE_ADMIN');
    }

如此一來就可以存取 /demo/secured/hello/admin/world 頁面了~












No comments:

Post a Comment