web-dev-qa-db-ja.com

セキュリティトランスペアレントメソッドXがセキュリティクリティカルメソッドYにアクセスしようとしましたが失敗しました

かなり安定したサーバーアプリケーションのバージョンを数十の顧客に1年近く導入しています。

最近、1人の新しい顧客がアプリケーションをセットアップし、次のエラーが発生しています。

System.MethodAccessException:セキュリティ透過メソッド[SomeMethod]によるセキュリティクリティカルメソッド[SomeOtherMethod]へのアクセスの試みが失敗しました。

SomeMethodとSomeOtherMethodはどちらも、私が書いたアセンブリのメソッドであり、.NET 4に対してビルドされ、Windowsサービス内で実行されています。違いがある場合、SomeOtherMethodは.NET 2.0に対してビルドされたサードパーティアセンブリ(EntLib 4.1)からの型を参照します。 EntLib 4.1のコードを見ると、SecurityTransparent属性とAPTC属性の両方が使用されていることがわかりますが、これによって他のクライアントで問題が発生することはありません。

これらのアセンブリは.NET 2.0 CLRからアップグレードされましたが、かなり前のことです。この正確なコードは他のお客様でも問題なく実行されており、APTC属性を明示的に使用したり、SecurityCritical属性をどこで使用したりすることもありません。

これは、構成の問題またはおそらく.NET Frameworkのパッチの問題であるという結論に導きます。この重大な変更を引き起こす.NET用のパッチがリリースされましたか?デフォルトでオフになっているこのタイプのチェックを実施するが、私の顧客が有効にしている可能性がある構成設定はありますか?

最後のポイントです。私のサービスでは、SSRS RDLCを使用してPDFを生成しています。 .NET 4の一部の変更により、次の構成を使用して、サービスにレガシーセキュリティポリシーを強制的に使用させる必要があります。

  <runtime>
    <NetFx40_LegacySecurityPolicy enabled="true" />
  </runtime>

これを行う必要がある理由の詳細については、このstackoverflowの投稿を参照してください: 。NET 4.0での非常に高いメモリ使用量

重要な点は、他のすべての顧客でもこれを行うことです。この1人の顧客のみが問題を抱えています。

21
RMD

ため息、エンタープライズライブラリを担当するMicrosoft Patterns And Practicesチームが採用したパターンと実践は、かなり嘆かわしいものです。まあ、例外は正確です。「まあ、私はセキュリティをチェックしないので、チェックのためにCPUサイクルを燃やす必要はありません」で修飾されたコードから、「セキュリティを確実にチェックします」と修飾されたメソッドを呼び出すことはできません。 。これは、Javaで使用される例外仕様と同様に拡張されます。 CASは非常に便利ですが、例外の診断は大きな頭痛の種であり、多くの場合、所有していない修正できないコードが含まれます。 .NET 4で廃止された大きな理由。

編集完了。問題を解決するには、ここでCASが強制されている理由を見つける必要があります。その最も簡単な説明は、サービスが完全な信頼で実行されないことです。 thatの最も簡単な説明は、クライアントがローカルハードドライブにサービスをインストールしなかったことです。または、通常、ローカルアセンブリでもコードをDon-Trust-Itモードで実行しているので、非常に偏執的な管理者はそれを好むでしょう。これは、コマンドラインオプションがCASと同じくらい不思議なツールであるCaspol.exeで構成する必要があります。信頼できない場所の説明でポットシューティングを行う場合、クライアントはこの ブログ投稿 に示すようにCaspolを実行する必要があります。または、単にサービスをローカルにデプロイするだけで、デフォルトの「私はあなたを信頼しています」が適用されます。

OPによって発見された実際の理由での編集:信頼できないインターネットまたはネットワークの場所からダウンロードされたときにファイルに追加される 代替データストリーム に注意してください。ファイルは、「ZoneId」値を使用して、どこから来たかを追跡する「Zone.Identifier」という名前のストリームを取得します。ストレージの場所から派生した信頼を上書きするのはその値です。通常はインターネットゾーンに配置します。エクスプローラを使用してファイルを右クリックし、[ブロックを解除]をクリックしてそのストリームを削除します。あなたがファイルを信頼できると確信した後:)

22
Hans Passant

それが他の人を助ける場合に備えて、この問題の私の解決策を投稿します:

1)AssemblyInfo.csで、[Assembly:SecurityTransparent]行を削除またはコメント化しました。

2)実際のジョブを実行するクラスとメソッドは[SecuritySafeCritical]としてマークされました。私の場合、ネットワーク接続を確立しています:

[SecuritySafeCritical]
public class NetworkConnection : IDisposable
{
    [SecuritySafeCritical]
    public NetworkConnection(string networkName, NetworkCredential credentials)
    {
        .............
    }
}

3)呼び出し元のクラスとメソッドは[SecurityCritical]として市場に出ました:

[SecurityCritical]
public class DBF_DAO : AbstractDAO
{
    [SecurityCritical]
    public bool DBF_EsAccesoExclusivo(string pTabla, ref ArrayList exepciones)
    {
        ....
        using (new NetworkConnection(DBF_PATH, readCredentials))
        {
            ....
        }
    }
}
10
Jhollman

ServiceModelExライブラリを使用しているときに http://www.idesign.net/ からダウンロードしたWCFサンプルを実行しているときに、同様の問題に直面していました。 ServiceModelExプロジェクトのAssemblyInfo.csの以下の行をコメント化しました

//[Assembly: AllowPartiallyTrustedCallers]

そしてそれは私のために働いた。

9
Hemendr

私の場合、ソリューションでNuGetパッケージを管理したときに問題がありました。メインのWebサイトプロジェクトで、一部のパッケージがSystem.Web.Mvcアセンブリバージョンバインディングをオーバーライドします。 4.0.0.0に戻します(5.0をインストールしました)。 Mvc v4.0がインストールされ、GACを介してアクセスできるため、変更に気づきませんでした。後退

0