3

Web API を実装しました。

<authentication mode="None" />

私は基本認証を使用しており、AuthorizeAttribute で Thread.CurrentPrincipal を設定しています。

アプリケーションを起動/デバッグした後、初めてリクエストを送信し、サーバー側で Thread.CurrentPrincipal (IsAuthenticated = true) を設定すると、IsAuthenticated はコントローラーで true を返します。ただし、この後のすべての要求では、Thread.CurrentPrincipal が通常どおりに設定されますが、実行がコントローラー メソッドに到達するまでに、コントローラーの User.Identity プロパティが変更され、IsAuthenticated = false になります。

アプリケーションのみを起動した後、初めて IsAuthenticated=true の理由がわかりません?! Thread.CurrentPrinciple を手動で設定しているので、毎回行う必要がありますが、そこからコントローラーを叩くまでのどこかで、置き換えられています!

アップデート

これは、私が追加した MediaTypeFormatter と関係があります。フォーマッタを削除すると、問題は発生しません。実行されるフォーマッタのコードは次のとおりです。

public override Task<object> ReadFromStreamAsync(Type type, System.IO.Stream webStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
    {
        return Task.Factory.StartNew(() =>
        {
            string temporaryFilePath = Path.Combine(TemporaryDirectory, Path.GetRandomFileName());

            using (FileStream fileStream = new FileStream(temporaryFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
            {
                webStream.CopyTo(fileStream);
            }

            return (object)new CustomFile(temporaryFilePath);
        });
    }
4

1 に答える 1

2

答えはここで詳しく説明されています。

つまり、Thread.CurrentPrincipal を設定するだけでは不十分です。HttpContext.Current.User も設定しましたが、動作しています。

元の投稿では、MediaTypeFormatter の非同期メソッドが呼び出され、追加のスレッドが作成され、CurrentPrinciple が他のスレッドにアタッチされ、コントローラー アクションが実行されるスレッドではありませんでした。

なぜ 2 か所に設定する必要があるのか​​については、こちらで説明されています。それは言います:

アプリケーションがカスタム認証ロジックを実行する場合、次の 2 つの場所でプリンシパルを設定する必要があります。

Thread.CurrentPrincipal: このプロパティは、.NET でスレッドのプリンシパルを設定する標準的な方法です。HttpContext.Current.User: このプロパティは ASP.NET に固有です。

次のコードは、プリンシパルを設定する方法を示しています。

private void SetPrincipal(IPrincipal principal)
{
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
        HttpContext.Current.User = principal;
    }
}

Web ホスティングの場合、両方の場所でプリンシパルを設定する必要があります。そうしないと、セキュリティ コンテキストが矛盾する可能性があります。ただし、セルフホスティングの場合、HttpContext.Current は null です。したがって、コードがホストに依存しないことを確認するには、示されているように、HttpContext.Current に割り当てる前に null を確認してください。

于 2013-06-13T21:27:34.917 に答える