2

Taiseer Joudeh によるこの非常に素晴らしい例で示されているのと同じトークン ベースの認証メカニズムを使用するアプリケーションを実装しようとしています。

私のアプリケーションでは、Cors の問題に遭遇し続けました。構成によっては、POST がトークンを取得するためのプリフライト (OPTIONS) リクエストで 500 エラーが発生するか、トークンを取得できても、実際の API 呼び出しに対する GET リクエストのプリフライト リクエストで 404 エラーが発生します。ベアラー トークン。

1 つの違いは、Taiseer のコードが IISExpress (または Azure) でホストされるようにセットアップされ、私のコードはローカル IIS (現時点では Windows 7 で実行中) でホストされていることです。

直感で、彼の API をローカル IIS でホストしようとしたところ、まったく同じ問題が見つかりました。(トークンのプリフライト リクエストで 500 エラーが発生し、実際の API は正常に動作するようです)

私が読んでいる限りでは、これは IIS のモジュールとハンドラーと WebApi の Cors 実装の間で何らかの競合があるように見えますが、Taiseer の実装は Azure でホストされている場合に機能するため、おそらく IIS のバージョンの違いです (I' m は現在 Windows 7 で実行されています)。

問題の原因を突き止めるにはどうすればよいですか?

4

3 に答える 3

2

問題の根本

Token アクションはコントローラでホストされていませんが、代わりに下位レベルの配管のどこかに組み込まれています。このメカニズムへの唯一のアクセスは、継承GrantResourceOwnerCredentials()するクラスのオーバーライド メソッドを使用することOAuthAuthorizationServerProviderです。(私たちの場合はですApplicationOAuthProvider.cs)。

GrantResourceOwnerCredentials()利用可能なコンテキストがありますが、PreFlight リクエストの一部として呼び出されないため、CORS に適切な PreFlight レスポンス ヘッダーを挿入する方法がありません。

ソリューション

最終的に、次の解決策に落ち着きました。これらのヘッダーをすべての応答に強制するため、私はそれの大ファンではありませんが、少なくとも機能します。

解決策は、Global.asax の Application_PreSendRequestHeaders() メソッドをオーバーライドして、適切なヘッダーを挿入することでした。

Global.asax.cs

    void Application_PreSendRequestHeaders(Object sender, EventArgs e)
    {
        var origin = Request.Headers.Get("Origin");
        var validOrigins = ConfigurationManager.AppSettings["allowedCorsOrigins"].Split(',');
        if(validOrigins.Any(o => o == origin))
        {
            Response.Headers.Set("Access-Control-Allow-Origin", origin);
            Response.Headers.Set("Access-Control-Allow-Credentials", "true");
            Response.Headers.Set("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, withcredentials, Prefer");
            Response.Headers.Set("Access-Control-Expose-Headers", "Claims, *");
            Response.Headers.Set("Access-Control-Max-Age", "600");
            Response.Headers.Set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
        }
    }

これには、次の web.config エントリが必要です。

web.config

<configuration>
  <appSettings>
    <add key="allowedCorsOrigins" value="http://www.allowedsite1.net,http://localhost:22687" />
    <add key="allowedCorsMethods" value="get, post, put, delete, options, batch" />
    <add key="allowedCorsHeaders" value="*" />
  </appSettings>
...
</configuration>

有効なオリジンを検索するループの理由は、許可されたオリジンのリストで応答できないためです...

これにより、1 つの例外を除いてほとんどの問題が解決されました (私の記憶が正しければ、PUT 動詞と DELETE 動詞の問題でした)。これには、「ExtensionlessUrlHandler-Integrated-4.0」を削除し、web.config のハンドラー セクションにパスと動詞を付けて再度追加する必要がありました。

web.config (2 回目の変更)

<system.webServer>
    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="" />
    </handlers>
    ....
</system.webServer>

CORS 関連の便利なリンク

于 2016-06-21T16:46:58.027 に答える
2

使用している IdentityServer ではありませんが、同じ問題である可能性があります。IdentityServer のGithub ページに関しては、IIS で実行する場合、アプリケーションの RAMMFAR (runAllManagedModulesForAllRequests) を有効にする必要があります。

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
  </modules>
</system.webServer>
于 2016-04-20T08:12:14.667 に答える
1

私はこれと同じ問題を抱えていました。トム・ホール氏の提案に従ってすべてを行いました。しかし、それでもクロムはAccess-control-allow-originヘッダーが存在しないと報告しました..フィドラーで調べた後、リクエストがプロキシサーバーを通過し、プロキシサーバーがプリフライトオプションリクエストを処理していることに気付きました..

そのため、「インターネットオプション」でプロキシサーバーを削除したところ、すべてが機能していることがわかりました... !!!

于 2016-11-03T16:30:48.450 に答える