それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

symfonyにはユーザー認証が組み込まれている。

symfonyはうれしい。ユーザー認証をsymfonyが組み込み機能として持っている。
init-app したら myUser.phpが作られるのはこのためだろう。

アクセス制限する方法には3通りほどあるって。マニュアルによると、アクセス制限を理解するためには、symfonyMVCのC部分 Front controllerを理解したほうがいいよって書いてある。

とりあえず、そこはすっ飛ばして、セキュリティーの部分を読んでみた。

3通りの方法を組み合わせる

今のところ理解したのは、次の3通り。どれかひとつでもいいし、組み合わせて使うと便利らしい。ただ、Session管理はプラグインに任せたほうがいいらしい。

1. security.ymlと認証モジュールを作る
2. MyActionClass 内に validateMyAction()メソッドを作る
3. フィルターを使って認証する

アクセス許可にはグループ(ロール)の概念があるようだ

マニュアルの「credentials」に適当な日本語が見つからない。どうも、役割(role)かチーム(group)のことらしい。つまりユーザー毎に許可を与える方法と、グループごとに許可を与える方法があるようだ。

validateMyActionが呼び出されるまで。

Figure 6-2 - The validation processが見にくいのでTEXTにしてみた。これも、みにくいw

MyAction呼び出し。
 |
validateMyAction()
 があるか?     
 |
 +----<ある>--validateMyAction()
 |                 実行
 |                  |
<ない>              +--<false>--handleErrorMyAction()がある--<ある>--handleErrorMyAction()を実行して終了
 |                  |                  |                                    
 |                <true>             +----<ない>-------------------------------+
 |                  |                                                              |
 +-----------executeMyAction()--<true>---executeMyAction()実行--<sView::ERROR>---myActionError()
                  がある?            |
                    |                      <sView::SUCCESS>
                  <false>            |
                    |                          |
             404ActionをCall              myActionSuccsess()

じゃぁ何処に認証を組み込むの?

わからないw

Filterかvalidateか。でもvalidateはフォームの検証にも使うみたい、それならば使いたくないかも。Filterで認証は、好きじゃない。security.ymlにアクション毎のアクセス制限が書けるんだからそれが一番管理しやすいかも。

admin-generatorでsecurityはどうする?

adminで作ってたら アクション定義がないじゃん。どうすんだ? URLを眺めると、MyAPP/[create,delete,list,edit]なので、たぶんコレが名前だろだろう。
試してみた

all:
  is_secure: off

list:
  is_secure: on

list/id にアクセスしたら 認証が必要です。っていわれたよ。

security.ymlに記述するするのが一番楽っぽい。

認証が必要なページはHTTP 200 ok か?

認証が必要ってsymfonyのメッセージが出る。そのときの、HTTPの内容をキャプチャしてみた。

HTTP/1.1 200 OK

なんか気持ち悪いけど。コレで良いのかなぁ?

HTTP/1.1 403 Forbidden

じゃないのかなぁ。。。どっちがふさわしいだろう。
SymfonyのTicketに上げた方が良いよなぁ。

symfonyのadmin generatorのDELETE

admin-genarator で作った削除用のURL。ブラウザから直接叩いてみる。

http://host/index.php/APP/delte/id/1

にアクセス。あ・・、あっさり実行された。つまりadmin generator は管理者用で公開用じゃないって事かな。CSRFに思い切り弱いw。DBのデータと密接に関連してるからしかたない。これじゃ公開用APPは作れない。。。

とりあえず、読んだところは和訳してみた。

和訳しながら読んだので、メモのためにコピペ張っておく。

Action Security

アクションのセキュリティー
The ability to execute an action can be restricted to users with certain privileges. The tools provided by symfony for this purpose allow the creation of secure applications, where users need to be authenticated before accessing some features or parts of the application. Securing an application requires two steps: declaring the security requirements for each action and logging in users with privileges so that they can access these secure actions.

実行する許可をユーザー毎に制限できる。アクセス制限は、symfonyがやってくれる。ユーザー認証の仕組みをページ毎に組み込める。全てのアプリ実行前に認証を組み込むことができる。認証を組み込むには2ステップの作業が必要で、どのページ(action/app)に認証を組み込むかを設定して、認証アプリケーションにどのモジュールを使うかをを設定する

Access Restriction

アクセス制限
Before being executed, every action passes by a special filter that checks if the current user has the privileges to access the requested action. In symfony, privileges are composed of two parts:

全てのアクションには、実行前にフィルタ機構を組み込むことができる。フィルタにより、現在のユーザーがアクセスしようとするベー時の実行権限があるかどうかチェックできる。symfonyでは実行権限の設定にはには2種類ある。

  • Secure actions require users to be authenticated.

ユーザー毎にアクセス許可を与える

  • Credentials are named security privileges that allow organizing security by group.

 ユーザーをグループに分けてグループにアクセス許可を与える

Restricting access to an action is simply made by creating and editing a YAML configuration file called security.yml in the module config/ directory. In this file, you can specify the security requirements that users must fulfill for each action or for all actions. Listing 6-23 shows a sample security.yml.

アクセス制限はsecurity.yml にYAML形式で設定を書くだけで簡単に実現できる。security.yml は config/ に作る、または既存を編集する。security.yml 内で、どのモジュール、アクションにアクセス制限をするかを記述する。以下の例を参考に。

Listing 6-23 - Setting Access Restrictions, in

apps/myapp/modules/mymodule/config/security.yml

read:
  is_secure:   off       # All users can request the read action

update:
  is_secure:   on        # The update action is only for authenticated users

delete:
  is_secure:   on        # Only for authenticated users
  credentials: admin     # With the admin credential

all:
  is_secure:  off        # off is the default value anyway

Actions are not secure by default, so when there is no security.yml or no mention of an action in it, actions are accessible by everyone. If there is a security.yml, symfony looks for the name of the requested action and, if it exists, checks the fulfillment of the security requirements. What happens when a user tries to access a restricted action depends on his credentials:

初期設定では、もちろん制限なし。または何も記述されていない。なので誰でも閲覧可能な状態。symfonyはsecurity.ymlを探して、リクエストされたページ(action名)のアクセス制限状態を調べる。実行権限のチェックがどのように遷移するかは以下の通り


If the user is authenticated and has the proper credentials, the action is executed.
If the user is not identified, he will be redirected to the default login action.
If the user is identified but doesn't have the proper credentials, he will be redirected to the default secure action, shown in Figure 6-1.

The default login and secure pages are pretty simple, and you will probably want to customize them. You can configure which actions are to be called in case of insufficient privileges in the application settings.yml by changing the value of the properties shown in Listing 6-24.

  1. ユーザーが認証済みで、実行権限があれば、アクションは実行される
  2. ユーザーが未認証なら、認証ページへ飛ばされる(defaultに設定したloginアクションへ)
  3. ユーザーが認証していても、実行権限がない場合は、securityアクションにより実行が制限されてHTTPと権限なしのメッセージが表示される。


ログインとセキュアページはとてもシンプル、なのでカスタマイズして使いまわせる。権限が無いときのActionを作って、settings.ymlでそれを実行するように設定すればいい。設定例は以下の通り

all:
  .actions:
    login_module:           default
    login_action:           login

    secure_module:          default
    secure_action:          secure

Granting Access/権限の付加
To get access to restricted actions, users need to be authenticated and/or to have certain credentials. You can extend a user's privileges by calling methods of the sfUser object. The authenticated status of the user is set by the setAuthenticated() method. Listing 6-25 shows a simple example of user authentication.

制限されたActionは、必要な実行権限か認証をユーザーに要求する。それにはユーザーの権限をsfUserの組み込みメソッドを使って権限を拡張する。認証状態は、setAthenticated()メソッドで設定できる。これが一番シンプルな認証。

Listing 6-25 - Setting the Authenticated Status of a User

class myAccountActions extends sfActions
{
  public function executeLogin()
  {
    if ($this->getRequestParameter('login') == 'foobar')
    {
      $this->getUser()->setAuthenticated(true);
    }
  }
 
  public function executeLogout()
  {
    $this->getUser()->setAuthenticated(false);
  }
}


Credentials are a bit more complex to deal with, since you can check, add, remove, and clear credentials. Listing 6-26 describes the credential methods of the sfUser class.

グループごとの実行権限は、ちょっと複雑で、権限をチェック、追加、削除、一括消去(?) を行う。以下の例を参考に

Listing 6-26 - Dealing with User Credentials in an Action

class myAccountActions extends sfActions
{
  public function executeDoThingsWithCredentials()
  {
    $user = $this->getUser();
 
    // Add one or more credentials
    // ユーザーにfoo グループの実行権限を与える
    // ユーザーにfoo,bar グループの実行権限を与える
    $user->addCredential('foo');
    $user->addCredentials('foo', 'bar');
 
    // Check if the user has a credential
    //ユーザーの実行権限を調べる
    echo $user->hasCredential('foo');                     =>   true
 
    // Check if the user has one of the credentials
    // foo bar のうちどちらかの権限があるか。
    // 
    echo $user->hasCredential(array('foo', 'bar'));       =>   true
 
    // Check if the user has both credentials
    // foo bar 両方の権限を持っているか
    echo $user->hasCredential(array('foo', 'bar'), true); =>   true
 
    // Remove a credential
    // foo の権限を取りあげる
    $user->removeCredential('foo');
    echo $user->hasCredential('foo');                     =>   false
 
    // Remove all credentials (useful in the logout process)
    // 全ての実行権限を取り上げる(ログアウト処理に便利)
    $user->clearCredentials();
    echo $user->hasCredential('bar');                     =>   false
  }
}


If a user has the 'foo' credential, that user will be able to access the actions for which the security.yml requires that credential. Credentials can also be used to display only authorized content in a template, as shown in Listing 6-27.

ユーザーが'foo' グループなら、ユーザーはアクセスできるように sectriy.ymlに記述する。権限の有無で表示を変えるテンプレート作成例は以下の通り

Listing 6-27 - Dealing with User Credentials in a Template

<ul>
  <li><?php echo link_to('section1', 'content/section1') ?></li>
  <li><?php echo link_to('section2', 'content/section2') ?></li>
  <?php if ($sf_user->hasCredential('section3')): ?>
  <li><?php echo link_to('section3', 'content/section3') ?></li>
  <?php endif; ?>
</ul>


As for the authenticated status, credentials are often given to users during the login process. This is why the sfUser object is often extended to add login and logout methods, in order to set the security status of users in a central place.


認証プロセスの中で実行権限はユーザーに付与されるように作ることが多い。実行権限は一箇所で設定できるようにするため、sfUserオブジェクトがlogin logoutメソッド持つように拡張されることが多い。

infomation
Among the symfony plug-ins, the sfGuardPlugin extends the session class to make login and logout easy. Refer to Chapter 17 for more information.
sfGuardPlugin を使えば、symfonyのSessionクラスを拡張でき、ログイン/ログアウトを簡単に作れるようなる。17章で詳細を解説します。


Complex Credentials/実行権限を細かく設定。
The YAML syntax used in the security.yml file allows you to restrict access to users having a combination of credentials, using either AND-type or OR-type associations. With such a combination, you can build a complex workflow and user privilege management system--for instance, a content management system (CMS) back-office accessible only to users with the admin credential, where articles can be edited only by users with the editor credential and published only by the ones with the publisher credential. Listing 6-28 shows this example.

YAML形式のsecurity.ymlで要求する実行権限を細かく設定することができる。AND/ORによる指定で、権限をまとめて表現できる。これを使えばアクセス制限が必要なシステム、たとえば、CMSや企業向けのシステムなど、これらに必要なアクセス権限設定を組み込める。

#編集を管理者チームで記事編集の許可を持つ人に限定
editArticle:
  credentials: [ admin, editor ]              # admin AND editor

#記事公開を管理者チームで公開責任者
publishArticle:
  credentials: [ admin, publisher ]           # admin AND publisher

#ユーザー管理を管理者、またはスーパーユーザーに限定。
userManagement:
  credentials: [[ admin, superuser ]]         # admin OR superuser


Each time you add a new level of square brackets, the logic swaps between AND and OR. So you can create very complex credential combinations, such as this:

YAML内のどこででも、[]配列を使ってAND/ORのロジックを書き換えられる。複雑な権限の実現例は以下の通り

credentials: [[root, [supplier, [owner, quasiowner]], accounts]]
             # root OR (supplier AND (owner OR quasiowner)) OR accounts