Page7アクセス許可を取り戻す(Assert)DenyやPermitOnlyを利用すると、その後でDemandが行われたときにチェックされるアクセス許可の内容が変更され、より厳しい検査を受けることになる。Frameworkには、反対に、いまは与えられていないが本来与えられているアクセス許可を取り戻して、自分に適用されるアクセス許可を緩くする機能もある。それがAssertだ。Assertも、Demand、Deny、PermitOnlyと同様に、メソッドとして呼び出すことも、属性として指定することもできる。冒頭で示したPermTestとDBAccessのコードが、それぞれ次のようになっていたとしよう。デリゲートの設定によって、結果的に処理がPermTestクラスに戻ってくるわけだ。{}reader.Close();cn.Close();}}デリゲート経由でデータベース処理が呼び出されるように修正したPermTest.csこの場合、DBAccessアセンブリがLocalIntranetのアクセス許可セットを持っているため、コールスタックを順にたどっていった結果、DBAccessのところでセキュリティ例外となる(図6)。上記のコードでは、DBAccessアセンブリがLocalIntranetのアクセス許可セットを持っているため、コールスタック調査の結果、DBAccessのところでセキュリティ例外となる。ところが、PermTestクラスのCallbackメソッドに次の属性が付いているか、またはメソッドの先頭で次のようなメソッド呼び出しが行われていると、話が変わってくる。SqlClientPermission(PermissionState.Unrestricted);perm.Assert();Assertを行うと、図7のようにコールスタックが変更され、Assertが行われた場所までしかアクセス許可のチェックが及ばなくなる。この場合はAssertの直後にSqlConnectionクラスのOpenメソッドを呼び出しているため、OpenメソッドのDemandでチェックされるのはPermTestアセンブリだけとなる。Serverへのアクセスが可能となる。DBAccessアセンブリが介在していることは無視されるのだ。Assertにより調査されないコールスタックAssertの直後にSqlConnectionクラスのOpenメソッドを呼び出しているため、OpenメソッドのDemandでチェックされるのはPermTestアセンブリだけとなる。敏感な読者ならすぐに分かるとおり、Assertはそれ自体がセキュリティ・ホールであるかのような機能になっている。Frameworkでは、Assertを行うためには「Assertを行ってもよい」というアクセス許可が必要になる。具体的には、System.Security.Permissions.SecurityPermissionクラスに、フラグとしてSystem.Security.Permissions.SecurityPermissionFlag.Assertionがセットされているアクセス許可を持っていなければならない。Assertを行うと、まず下の図8のようにコールスタック全体がAssertを行うアクセス許可を持っているかどうか確認され、すべてがOKとなって初めて図7のようにコールスタックが変更されるということだ。LocalIntranetのアクセス許可セットではAssertが許可されているため、上記のPermTestとDBAccessの組み合わせの場合はAssertが成功する。インターネットからダウンロードされたアセンブリにはデフォルトではAssertが許可されていないため、Assertを呼び出して自分のアクセス許可設定を緩くすることはできない。コールスタックにおけるAssertの確認Assertを行うと、コールスタック全体がAssertを行うアクセス許可を持っているかどうか確認され、すべてがOKとなって初めてコールスタックが変更される。LocalIntranetのアクセス許可セットではAssertが許可されているため、この図の組み合わせの場合はAssertが成功する。Assertは非常に強力な機能なので、何らかの理由でデフォルトのポリシーを変更した独自のポリシーを作成する場合には注意してほしい。本来不要なはずのアセンブリにAssertの許可を与えてしまうと、コード・アクセス・セキュリティの機能は台無しになってしまう。7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。TranslatorはPowerPoint用のアドイン。