認証と認可

Authentication is a process of verifying whether someone is who he claims he is. It usually involves a username and a password, but may include any other methods of demonstrating identity, such as a smart card, fingerprints, etc. 認証とは、自分が自分であることを確認するプロセスです。通常は、ユーザー名とパスワードでしょうが、スマート・カード、指紋などの同一性を実証する方法としてもつかうことができます。 Authorization is finding out if the person, once identified, is permitted to manipulate specific resources. This is usually determined by finding out if that person is of a particular role that has access to the resources. 認可は、以前識別された人が特定のリソースを操作することを許されるかどうか検索します。通常、その人がそのリソースにアクセスする特定のロールの人にであるかを検索することにより決定されます。

プラード認証・認可フレームワークはどのように働くか

PRADO provides an extensible authentication/authorization framework. As described in application lifecycles, TApplication reserves several lifecycles for modules responsible for authentication and authorization. PRADO provides the TAuthManager module for such purposes. Developers can plug in their own auth modules easily. TAuthManager is designed to be used together with TUserManager module, which implements a read-only user database. PRADOは拡張可能な認証/認可フレームワークを提供します。アプリケーションライフ・サイクルに記載されている様に、TApplicationは認証と認可の原因であるモジュールのためにいくつかのライフ・サイクルを用意してあります。PRADOはTAuthManagerモジュールをその酔うな目的で提供しています。開発者は自身の認証/認可モジュールを容易に差し込むことができます。TAuthManagerは、TUserManagerモジュールと一緒に使用されることを目指しています。それは読み出し専用のユーザ・データベースをインプリメントします。 When a page request occurs, TAuthManager will try to restore user information from session. If no user information is found, the user is considered as an anonymous or guest user. To facilitate user identity verification, TAuthManager provides two commonly used methods: login() and logout(). A user is logged in (verified) if his username and password entries match a record in the user database managed by TUserManager. A user is logged out if his user information is cleared from session and he needs to re-login if he makes new page requests. ページ・リクエストが生じる時、 TAuthManagerはセッションからのユーザ情報を回復しようとします。ユーザ情報が見つからない場合、ユーザは匿名かゲスト・ユーザと見なされます。ユーザ同一性の立証のために、TAuthManagerは、ログインする ()およびログアウト()といった、2つの一般に用いられている方法を提供しています。ユーザーは、入力されたユーザー名とパスワードがTUserManagerによって管理されたユーザ・データベースのレコードと一致する場合、正当性が確保されログインすることができます。また、ログアウトされたときは、そのユーザ情報がセッションから取り除かれ、もし再度新しいページ・リクエストがなされれば、再ログインする必要があります。
During Authorization application lifecycle, which occurs after Authentication lifecycle, TAuthManager will verify if the current user has access to the requested page according to a set of authorization rules. The authorization is role-based, i.e., a user has access to a page if 1) the page explicitly states that the user has access; 2) or the user is of a particular role that has access to the page. If the user does not have access to the page, TAuthManager will redirect user browser to the login page which is specified by LoginPage property. 認可アプリケーションライフ・サイクル(それは認証ライフ・サイクルの後に生じます)中に、TAuthManagerは、カレント・ユーザーが認可ルールに沿ってリクエストされたページにアクセスしているかどうかを確認します。認可はロールベースになっています。すなわち、1)ページにそのユーザーがアクセスできると明示されているか、2)ユーザがあるページにアクセスする特定のロールをもっているなら、ユーザーはそのページにアクセスできます。もしユーザがページにアクセスできなければ、TAuthManagerはLoginPageプロパティによって指定されるログイン・ページをユーザ・ブラウザへ転送するでしょう。

プラード認証\/認可フレームワークの使用

To enable PRADO auth framework, add the TAuthManager module and TUserManager module to application configuration, PRADO 認証\/認可フレームワークを使用可能な状態にするためには、アプリケーション設定(ルートに配置されているApplication.xml)にTAuthManagerモジュールおよびTUserManagerモジュールを加えてください、
<serviceid="page"class="TPageService">
  <modules>
   <moduleid="auth" class="System.Security.TAuthManager"
                    UserManager="users"
                    LoginPage="UserLogin"/>
   <moduleid="users" class="System.Security.TUserManager"
                     PasswordMode="Clear">
    <username="demo" password="demo"/>
    <username="admin"password="admin"/>
   </module>
  </modules>
 </service>
In the above, the UserManager property of TAuthManager is set to the users module which is TUserManager. Developers may replace it with a different user management module that is derived from TUserManager. 上記のものでは、TAuthManagerのUserManagerプロパティは、TUserManagerであるユーザ・モジュールにセットされます。開発者は、それを、TUserManagerに由来する異なるユーザ管理モジュールに取り替えてもよい。
Authorization rules for pages are specified in page configurations as follows, ページの認可規則は、ページ設定(pagesディレクトリのconfig.xml)の中で以下のように指定されます.
<authorization>
 <allowpages="PageID1,PageID2"
  users="User1,User2"
  roles="Role1"/>
 <denypages="PageID1,PageID2"
  users="?"
  verb="post"/>
</authorization>
An authorization rule can be either an allow rule or a deny rule. Each rule consists of four optional properties: 認可規則はallow規則あるいはdeny規則のいずれかになりえます。支配はそれぞれ4つのオプションの特性から成ります。
  1. pages - list of comma-separated page names that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all pages under the current directory and all its subdirectories recursively.
  2. users - list of comma-separated user names that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all users including anonymous/guest user. A character ? refers to anonymous/guest user. And a character @ refers to authenticated users (available since v3.1).
  3. roles - list of comma-separated user roles that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all user roles.
  4. verb - page access method that this rule applies to. It can be either get or post. If empty, not set or wildcard '*', the rule will apply to both methods.
  1. pages - このルールが適用される、コンマに分離されたページ名のリスト。空欄、設定無し、もしくはワイルドカード「*」の場合には、ルールは、カレント・ディレクトリおよびそのすべてのサブディレクトリの下のすべてのページに再帰的に適用されます。
  2. user - この規則が適用されるコンマに分離されたユーザー名のリスト。空欄、設定無し、もしくはワイルドカード「*」の場合には、この規則は、含んでいること、匿名/ゲスト・ユーザを含む、すべてのユーザに適用されます。\"?\"文字は、匿名/ゲストユーザーのことを指し、また、"@"文字は確証されたユーザを指します。(この機能はv3.1以降利用可能です。)
  3. roles - この規則が適用されるコンマに分離されたユーザロールのリスト。空欄、設定無し、もしくはワイルドカード「*」の場合には、この規則はすべてのユーザロールに適用されるでしょう。
  4. verb - この規則が適用されるページ・アクセスメソッド。それは get もしくは、post のことです。空欄、設定無し、もしくはワイルドカード「*」の場合には、規則は両方のメソッドに適用されるでしょう。
When a page request is being processed, a list of authorization rules may be available. However, only the first effective rule matching the current user will render the authorization result. add
ページ・リクエストが処理されている場合、認可規則のリストは利用可能かもしれません。しかしながら、カレント・ユーザーと一致する最初の有効な規則だけが認可結果を与えるでしょう。
  1. Rules are ordered bottom-up, i.e., the rules contained in the configuration of current page folder go first. Rules in configurations of parent page folders go after.
  2. A rule is effective if the current page is in the listed pages of the rule AND the current user action (get or post) is in the listed actions.
  3. A rule matching occurs if the current user name is in the listed user names of an effective rule OR if the user's role is in the listed roles of that rule.
  4. If no rule matches, the user is authorized.
  1. 規則はボトム・アップ的に適用されます。つまり、現在のページ・フォルダーの設定(config.xml)に含まれていた規則が優先して適用され、親ページ・フォルダーの設定(application.xml等)の規則は劣後して適用されます。
  2. ルールにリストアップされたページに該当し、且つ、ルールにリストアップされたアクション(おそらくverbのことか?)(get もしくは post)に該当した場合にルールは有効となる。
  3. カレント・ユーザー名が有効なユーザー名にリストアップされているか、もしくは、そのユーザのroleが有効なルールのroleリストにある場合にルールは適用されます。
  4. すべてのルールが適用されない時には、そのユーザは認可されます。
In the above example, anonymous users will be denied from posting to PageID1 and PageID2, while User1 and User2 and all users of role Role1 can access the two pages (in both get and post methods). 上記の例においては、User1およびUser2、およびRole1をもつユーザのすべてがPageID1,PageID2の2ページにアクセス(get post の両方のメソッドで)することができる一方、匿名のユーザはこの2ページへpost方式でアクセスすることは拒否されます。

Prado3.1.1以降から可能となったこと

Since version 3.1.1, the pages attribute in the authorization rules can take relative page paths with wildcard '*'. For example, pages="admin.Home" refers to the Home page under the admin directory, and pages="admin.*" would refer to all pages under the admin directory and subdirectories.
バージョン3.1.1以降、認可規則の中のページ属性はワイルドカード‘*’によって相対的なページを選ぶことができます。 例えば、pages=「admin.Home」はadminディレクトリの下でホームページを参照し、pages=「admin.*」はadminディレクトリとサブディレクトリの下ですべてのページを参照するでしょう。
Also introduced in version 3.1.1 are IP rules. They are specified by a new attribute ips in authorization rules. The IP rules are used to determine if an authorization rule aplies to an end-user according to his IP address. One can list a few IPs together, separated by comma ','. Wildcard '*' can be used in the rules. For example, ips="192.168.0.2, 192.168.1.*" means the rule applies to users whose IP address is 192.168.0.2 or 192.168.1.*. The latter matches any host in the subnet 192.168.1. If the attribute 'ips' is empty, not set or wildcard '*', the corresponding rule will apply to requests coming from any host address.
バージョン3.1.1 では、IPルールも導入されました。それらは認可ルール中の新しい属性ipsによって指定されます。 IPルールは、認可ルールがエンドユーザーに(そのIPアドレスから判断し)適用されるかどうかを決定する為に使われます。コンマ'、'によって区切られて区切られた幾つかのIPアドレスをリスト化することすることができますし、ワイルドカード‘*’も使用可能です。 例えば、ips="192.168.0.2, 192.168.1.*" は、IPアドレスが192.168.0.2または192.168.1.* であるユーザーにあてはまることを意味しています。後者はサブネット192.168.1でどのようなホストとでもマッチします。属性‘ips’が空であるか、セットされていないか、またはワイルドカード‘*’である場合には、そこに書かれているルールは、すべてのホストアドレスからの要求に対して適用されます。

TUserManager を使用する

As aforementioned, TUserManager implements a read-only user database. The user information are specified in either application configuration or an external XML file. 前提としては、TUserManagerはリードオンリー ユーザーデータベースを実装します。 ユーザー情報はアプリケーションコンフィギュレーションまたは外付けのXMLファイルのどちらかにおいて指定されます。 We have seen in the above example that two users are specified in the application configuration. Complete syntax of specifying the user and role information is as follows, すでに上記の例で、2人のユーザーがアプリケーションコンフィギュレーションの中で指定されることを確認しましたが、ユーザーと役割role情報を指定する完全な構文は次の通りです。
<user name="demo" password="demo" roles="demo,admin" />
<role name="admin" users="demo,demo2" />
where the roles attribute in user element is optional. User roles can be specified in either the user element or in a separate role element. この例のユーザー要素の中のrole属性はオプションです。ユーザーroleはユーザー要素の中または別個の役割要素の中で指定されることができます。
<user  name="demo">
 <roles>demo</roles>
 <roles>admin</roles>
</user>
といった感じですね。

TDbUserManager を使用する

TDbUserManager is introduced in v3.1.0. Its main purpose is to simplify the task of managing user accounts that are stored in a database. It requires developers to write a user class that represents the necessary information for a user account. The user class must extend from TDbUser. TDbUserManagerはv3.1.0において導入されました。その主要な目的は、データベースに蓄えられるユーザーアカウントを管理する仕事を簡素化することです。 開発者は、ユーザーに、ユーザーアカウントのために必要な情報を表示するクラスを書くことが求められます。ユーザークラスはTDbUserから拡張しなければならないということです。 To use TDbUserManager, configure it in the application configuration like following: TDbUserManagerを使うためには、アプリケーションコンフィグ(Application.xml)中に次ようように設定をしてください。
<module id="db"
  class="System.Data.TDataSourceConfig" ..../>
  <module id="users"
    class="System.Security.TDbUserManager"
    UserClass="Path.To.MyUserClass"
    ConnectionID="db" />
  <module id="auth"
    class="System.Security.TAuthManager"
    UserManager="users" LoginPage="Path.To.LoginPage" />
In the above, UserClass specifies what class will be used to create user instance. The class must extend from TDbUser. ConnectionID refers to the ID of a TDataSourceConfig module which specifies how to establish database connection to retrieve user information. 上記の中で、UserClassは、ユーザーインスタンスを作成するために使われるクラスを指定します。クラスはTDbUserから拡張しなければなりません。ConnectionIDは、ユーザー情報を検索するためにどのようにデータベース接続を設立するかを指定するTDataSourceConfigモジュールのIDを参照します。 The user class has to implement the two abstract methods in TDbUser: validateUser() and createUser(). Since user account information is stored in a database, the user class may make use of its DbConnection property to reach the database. ユーザークラスは、TDbUserにおいてvalidateUser()とcreateUser()という2つの抽象的なメソッドを実装する必要があります。ユーザーアカウント情報がデータベースに蓄えられるので、ユーザークラスは、データベースつながるために、そのDbConnectionプロパティを活用します。

Prado3.1.1以降から可能となったこと

Since 3.1.1, TAuthManager provides support to allow remembering login by setting AllowAutoLogin to true. Accordingly, TDbUser adds two methods to facilitate the implementation of this feature. In particular, two new methods are introduced: createUserFromCookie() and saveUserToCookie(). Developers should implement these two methods if remembering login is needed. Below is a sample implementation: version3.1.1以降、TAuthManagerは、AllowAutoLoginを正常に設定することによって、ログインの記憶を許可するサポートを提供します。それに応じて、TDbUserは、この機能のインプリメンテーションを容易にする2つのメソッドを追加します。 特に、createUserFromCookie()とsaveUserToCookie()といった2つの新方式が導入されます 。開発者は、ログインの記憶が必要なら、これらの2つの方法を実施するべきです。以下はサンプルインプリメンテーションです:
public function createUserFromCookie($cookie)
{
   if(($data=$cookie->Value)!=='')
   {
       $application=Prado::getApplication();
       if(($data=$application->SecurityManager->validateData($data))!==false)
       {
           $data=unserialize($data);
           if(is_array($data) && count($data)===3)
           {
               list($username,$address,$token)=$data;
               $sql='SELECT passcode FROM user WHERE LOWER(username)=:username';
               $command=$this->DbConnection->createCommand($sql);
               $command->bindValue(':username',strtolower($username));
               if($token===$command->queryScalar() && $token!==false &&
$address=$application->Request->UserHostAddress)
                   return $this->createUser($username);
           }
       }
   }
   return null;
}

public function saveUserToCookie($cookie)
{
   $application=Prado::getApplication();
   $username=strtolower($this->Name);
   $address=$application->Request->UserHostAddress;
   $sql='SELECT passcode FROM user WHERE LOWER(username)=:username';
   $command=$this->DbConnection->createCommand($sql);
   $command->bindValue(':username',strtolower($username));
   $token=$command->queryScalar();
   $data=array($username,$address,$token);
   $data=serialize($data);
   $data=$application->SecurityManager->hashData($data);
   $cookie->setValue($data);
}